danogo-clmm 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sdk.d.mts +5 -1
- package/dist/sdk.d.ts +5 -1
- package/dist/sdk.js +1 -1
- package/dist/sdk.mjs +1 -1
- package/package.json +1 -1
package/dist/sdk.d.mts
CHANGED
|
@@ -54,7 +54,7 @@ interface SwapRequest {
|
|
|
54
54
|
pools: {
|
|
55
55
|
poolOutRef: string;
|
|
56
56
|
deltaAmount: bigint;
|
|
57
|
-
minOutChangeAmount
|
|
57
|
+
minOutChangeAmount?: bigint;
|
|
58
58
|
stakingOutRef?: string;
|
|
59
59
|
}[];
|
|
60
60
|
protocolConfigOutRef?: string;
|
|
@@ -160,6 +160,10 @@ declare class DanogoClmm {
|
|
|
160
160
|
* Helper function to handle staking rewards for ADA pools
|
|
161
161
|
*/
|
|
162
162
|
private getRewardAmount;
|
|
163
|
+
/**
|
|
164
|
+
* Helper function to get UTxO or throw error if not found
|
|
165
|
+
*/
|
|
166
|
+
private getUtxoOrThrow;
|
|
163
167
|
}
|
|
164
168
|
|
|
165
169
|
export { type ConcentratedPool, type PoolDatum, type QuoteSwapRequest, type SwapRequest, DanogoClmm as default };
|
package/dist/sdk.d.ts
CHANGED
|
@@ -54,7 +54,7 @@ interface SwapRequest {
|
|
|
54
54
|
pools: {
|
|
55
55
|
poolOutRef: string;
|
|
56
56
|
deltaAmount: bigint;
|
|
57
|
-
minOutChangeAmount
|
|
57
|
+
minOutChangeAmount?: bigint;
|
|
58
58
|
stakingOutRef?: string;
|
|
59
59
|
}[];
|
|
60
60
|
protocolConfigOutRef?: string;
|
|
@@ -160,6 +160,10 @@ declare class DanogoClmm {
|
|
|
160
160
|
* Helper function to handle staking rewards for ADA pools
|
|
161
161
|
*/
|
|
162
162
|
private getRewardAmount;
|
|
163
|
+
/**
|
|
164
|
+
* Helper function to get UTxO or throw error if not found
|
|
165
|
+
*/
|
|
166
|
+
private getUtxoOrThrow;
|
|
163
167
|
}
|
|
164
168
|
|
|
165
169
|
export { type ConcentratedPool, type PoolDatum, type QuoteSwapRequest, type SwapRequest, DanogoClmm as default };
|
package/dist/sdk.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var j=Object.defineProperty;var at=Object.getOwnPropertyDescriptor;var ct=Object.getOwnPropertyNames;var ut=Object.prototype.hasOwnProperty;var lt=(o,t)=>{for(var e in t)j(o,e,{get:t[e],enumerable:!0})},pt=(o,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ct(t))!ut.call(o,r)&&r!==e&&j(o,r,{get:()=>t[r],enumerable:!(n=at(t,r))||n.enumerable});return o};var ft=o=>pt(j({},"__esModule",{value:!0}),o);var Ot={};lt(Ot,{default:()=>Bt});module.exports=ft(Ot);var Z=require("@evolution-sdk/evolution"),$=require("@evolution-sdk/evolution/ScriptHash"),y=require("@evolution-sdk/evolution/Assets");function S(o,t){let n=(o>=0n?o:o+(1n<<256n)).toString(16);n.length%2&&(n="0"+n);let r=n.length/2;if(r>t)throw new Error(`Number ${o} requires ${r} bytes, but target length is ${t}.`);let i=new Uint8Array(t),s=t-r;for(let a=0;a<r;a++)i[a+s]=parseInt(n.slice(a*2,a*2+2),16);return i}var H=(o,t,e,n)=>{try{let r=(i,s)=>{let a=3n,p=S(o?i:n,1),m=S(a,1),l=t.map((A,I)=>{let h=s.find(f=>f.utxo.transactionId===A.transactionId&&f.utxo.index===A.index);if(!h)throw new Error(`Pool UTxO at ${I} not found in indexedInputs`);if(e[I]===void 0)throw new Error(`deltaAmount for poolOutIdx ${I} is undefined`);let g=S(BigInt(h.index),1),R=S(BigInt(I),1),T=S(e[I],32);return{poolInBytes:g,poolOutBytes:R,amountBytes:T}}),b=2+34*l.length,w=new Uint8Array(b),u=0;w.set(p,u),u+=p.length,w.set(m,u),u+=m.length;for(let A of l)w.set(A.poolInBytes,u),u+=A.poolInBytes.length,w.set(A.poolOutBytes,u),u+=A.poolOutBytes.length,w.set(A.amountBytes,u),u+=A.amountBytes.length;return w};return{all:i=>{if(!i.length)throw new Error("swapTokensRedeemer batch all called with empty indexedInputs");let s=null;if(o&&(s=i.find(a=>a.utxo.transactionId===o.transactionId&&a.utxo.index===o.index),!s))throw new Error("Target pool UTxO is not found in poolInUTxOs");return r(s?.index,i)},inputs:t}}catch(r){throw console.error("Error creating pool redeemer:",r),r}};var O=require("@evolution-sdk/evolution"),K=require("@evolution-sdk/evolution/InlineDatum");var x="lovelace";var mt="64d111b957e7d7848ffdde5149aa77fa4090a7fa1ad0ac108067900614848501#0",gt="d8b69fc53637bcfadbc4469083f706bc293f4d9d2296646c5ca167bb",dt="2cafd7c92f7093e5229af274be83dea660b0590b4174bbed79ba662b44fbd1ee#0";var wt="2e19cca74e3badcab26aef7574aa1885ba97228a254ca227ba2f79f2b75fd136#0",At="04041c3c6ba87b33f2c9eb7f7dbeae3b26003c3e199d438bb99932a2",It="3775af36f485f9c97101ee5b9b360c34f0f8e12186bc9060f358b7fc8ce468a4#0",X=o=>o===1?{poolScriptOutRef:mt,poolScriptHash:gt,protocolScriptOutRef:dt}:{poolScriptOutRef:wt,poolScriptHash:At,protocolScriptOutRef:It};var tt=o=>{let t=[new Uint8Array(Buffer.from(o.tokenX.slice(0,56),"hex")),new Uint8Array(Buffer.from(o.tokenX.slice(57),"hex"))],e=[new Uint8Array(Buffer.from(o.tokenY.slice(0,56),"hex")),new Uint8Array(Buffer.from(o.tokenY.slice(57),"hex"))],n=O.Data.constr(0n,[o.sqrtLowerPriceNum,o.sqrtLowerPriceDen]),r=O.Data.constr(0n,[o.sqrtUpperPriceNum,o.sqrtUpperPriceDen]),i=O.Data.constr(0n,[t,e,BigInt(o.lpFeeRate),o.platformFeeX,o.platformFeeY,o.totalSwapFee,n,r,o.minXChange,o.minYChange,o.circulatingLPToken,BigInt(o.lastWithdrawEpoch)]);return new K.InlineDatum({data:i})};var Y=o=>{let t;if(typeof o=="string")t=O.CBOR.fromCBORHex(o);else{let i=o.data,s=O.Data.toCBORHex(i);t=O.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 n=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]),p=s[1]instanceof Uint8Array?s[1]:new Uint8Array(s[1]),m=Buffer.from(a).toString("hex"),l=Buffer.from(p).toString("hex");return m===""&&l===""?x:m+"."+l}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:n(e[0]),tokenY:n(e[1]),lpFeeRate:Number(e[2]),platformFeeX:BigInt(e[3]),platformFeeY:BigInt(e[4]),totalSwapFee:BigInt(e[5]),sqrtLowerPriceNum:r(e[6]).num,sqrtLowerPriceDen:r(e[6]).den,sqrtUpperPriceNum:r(e[7]).num,sqrtUpperPriceDen:r(e[7]).den,minXChange:BigInt(e[8]),minYChange:BigInt(e[9]),circulatingLPToken:BigInt(e[10]),lastWithdrawEpoch:Number(e[11])}},V=o=>{let t,e=O.Data.toCBORHex(o.data);t=O.CBOR.fromCBORHex(e);let n=t._tag==="Tag"?t.value:t;if(!Array.isArray(n))throw new Error("Invalid datum structure: expected array of fields");return{platformFeeRate:BigInt(n[0]),swapFee:BigInt(n[1])}};var E=require("@evolution-sdk/evolution");function _(o){if(o===x)return{unit:x};let t=o.indexOf("."),e=t===-1?o:o.slice(0,t),n=t===-1?"":o.slice(t+1),r=E.Bytes.fromHex(e),i=new E.PolicyId.PolicyId({hash:r}),s=n?E.Bytes.fromHex(n):new Uint8Array(0),a=new E.AssetName.AssetName({bytes:s});return{policyId:i,assetName:a,unit:o}}var et=o=>{if(!o||Object.keys(o).length===0)return[];let t=[];for(let[e,n]of Object.entries(o)){if(e==="ada")continue;let r=[];for(let[i,s]of Object.entries(n))r.push({name:i,value:s});t.push({policyId:e,assets:r})}return t};var M=require("@evolution-sdk/evolution");var z=(o,t)=>{let e=432e6,n=1647899091e3,r=328;return t!==1&&(e=18e5),Math.floor((o-n)/e)+r};function yt(o,t,e,n,r=0n,i){let s=n<0n?-n:n,a=e.tokenX===x?3000000n+BigInt(e.totalSwapFee):0n,p=BigInt(o)-BigInt(e.platformFeeX)+r-a,m=BigInt(t)-BigInt(e.platformFeeY),l=ht(p,m,[BigInt(e.sqrtLowerPriceNum),BigInt(e.sqrtLowerPriceDen)],[BigInt(e.sqrtUpperPriceNum),BigInt(e.sqrtUpperPriceDen)]),b=nt(l[0]*BigInt(e.sqrtUpperPriceDen),l[1]*BigInt(e.sqrtUpperPriceNum))+p,w=nt(l[0]*BigInt(e.sqrtLowerPriceNum),l[1]*BigInt(e.sqrtLowerPriceDen))+m;return n>0n?ot(s,b,w,m,BigInt(e.lpFeeRate),i):ot(s,w,b,p,BigInt(e.lpFeeRate),i)}var ot=(o,t,e,n,r,i)=>{let s=10000n,p=o*r/s*BigInt(i)/10000n,m=s-r,l=t*s+o*m,b=t*e,u=(e*l-b*s)/l;if(u>n)throw new Error("pool out exceeded");return[u,p]},ht=(o,t,e,n)=>{let r=e[1]*n[1],i=e[0]*n[0],s=(t*r-o*i)*(t*r-o*i),a=4n*o*t*e[1]*e[1]*n[0]*n[0],p=Pt(s+a),m=t*r+o*i+p,l=2n*(n[0]*e[1]-n[1]*e[0]);return[m,l]};function Pt(o){if(o<0n)throw new Error("Square root of negative number");if(o<2n)return o;let t=o,e=t+o/t>>1n;for(;e<t;)t=e,e=t+o/t>>1n;return t}function nt(o,t){if(t===0n)throw new Error("Division by zero");let e=o/t;return o%t===0n||o<0n!=t<0n?e:e+1n}function rt(o,t){let n=[...t].sort((r,i)=>r.transactionId===i.transactionId?r.index<i.index?-1:1:r.transactionId<i.transactionId?-1:1).findIndex(r=>r.transactionId===o.transactionId&&r.index===o.index);if(n===-1)throw new Error("Protocol config out ref not found in reference inputs");return BigInt(n)}function Q(o,t,e){let n=[];for(let r=0;r<o.length;r++){let i=o[r],s=t[r];if(s===0n)continue;let[a,p]=yt(i.tokenAAmount,i.tokenBAmount,i.datum,s,i.rewardAmount,e);n.push({poolIndex:r,deltaAmount:s,outputAmount:a,platformFee:p})}return n}var N=o=>{if(!o)return;let[t,e]=o.split("#");return new M.TransactionInput.TransactionInput({transactionId:M.TransactionHash.fromHex(t),index:BigInt(e)})};var it=require("@evolution-sdk/evolution/Bytes32"),J=class{constructor(){}async calculateSwapOut(t,e){if(!t||!t.address)throw new Error("Please connect a wallet first.");let n=(await t.address()).networkId,r=z(Date.now(),n),i=await Promise.all(e.pools.map(u=>t.getUtxosByOutRef([N(u.poolOutRef)]))),s=X(n),a=e.protocolConfigOutRef??s.protocolScriptOutRef,p=(await t.getUtxosByOutRef([N(a)]))[0];if(!p.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let m=V(p.datumOption),l=await Promise.all(e.pools.map(async(u,A)=>{let I=i[A][0];if(!I.datumOption)throw new Error(`Pool input UTxO ${A} does not contain a datum.`);let h=Y(I.datumOption),g=_(h.tokenX),R=_(h.tokenY),T=I.assets.lovelace,f=k=>k.unit===x?T:(0,y.quantityOf)(I.assets,k.policyId,k.assetName),B=null;u.stakingOutRef&&(B=(await t.getUtxosByOutRef([N(u.stakingOutRef)]))[0]);let U=0n;return g.unit===x&&B&&r>h.lastWithdrawEpoch&&(U=await this.getRewardAmount(t,n,B)),{tokenAAmount:f(g),tokenBAmount:f(R),datum:h,rewardAmount:U}})),b=e.pools.map(u=>u.deltaAmount);return Q(l,b,m.platformFeeRate).map(u=>u.outputAmount)}async submitSwap(t,e){if(!t||!t.address)throw new Error("Please connect a wallet first.");let n=(await t.address()).networkId,r=z(Date.now(),n),i=await Promise.all(e.pools.map(async c=>(await t.getUtxosByOutRef([N(c.poolOutRef)]))[0])),s=X(n),a=s.poolScriptOutRef,p=e.protocolConfigOutRef??s.protocolScriptOutRef,m=(await t.getUtxosByOutRef([N(a)]))[0],l=(await t.getUtxosByOutRef([N(p)]))[0];if(!l.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let b=V(l.datumOption),w=[],u=[];for(let c=0;c<e.pools.length;c++){let d=e.pools[c],P=i[c];if(!P.datumOption)throw new Error(`Pool input UTxO ${c} does not contain a datum.`);let D=Y(P.datumOption),F=_(D.tokenX),q=_(D.tokenY),W=P.assets.lovelace,L=G=>G.unit===x?W:(0,y.quantityOf)(P.assets,G.policyId,G.assetName),C=null;d.stakingOutRef&&(C=(await t.getUtxosByOutRef([N(d.stakingOutRef)]))[0]),u.push(C),w.push({tokenAAmount:L(F),tokenBAmount:L(q),datum:D,utxo:P,tokenA:F,tokenB:q})}let A=e.pools.map(c=>c.deltaAmount),I=Q(w,A,b.platformFeeRate);I.forEach((c,d)=>{let P=e.pools[d].minOutChangeAmount;if(c.outputAmount<P)throw new Error(`Expected swap output at least ${P} but got ${c.outputAmount}`)});let h=I.reduce((c,d)=>c+d.deltaAmount,0n),g=e.pools.find(c=>c.deltaAmount!==0n);if(!g)throw new Error("At least one pool must have a non-zero delta amount");let R=g.deltaAmount>0?w[0].tokenA:w[0].tokenB,T=await this.getUserTokenBalance(t,R);if(T<h)throw new Error(`Insufficient ${R.unit} balance. Required: ${h}, Available: ${T}`);let f=t.newTx(),B=[l];B.push(m),u.forEach(c=>{c&&B.push(c)}),f=f.readFrom({referenceInputs:B});let U=rt(l,B);f=f.withdraw({stakeCredential:(0,$.fromScript)(m.scriptRef),amount:0n,redeemer:H(null,i,A,U)});for(let c=0;c<w.length;c++){let d=w[c],P=I.find(C=>C.poolIndex===c);if(!P)continue;let D=P.deltaAmount,F=P.platformFee,q=tt({...d.datum,platformFeeX:BigInt(d.datum.platformFeeX)+(D>0?F:0n),platformFeeY:BigInt(d.datum.platformFeeY)+(D<0?F:0n),lastWithdrawEpoch:r,totalSwapFee:BigInt(d.datum.totalSwapFee)+BigInt(b.swapFee)}),W=this.buildDeltaAssets(D>0?d.tokenA:d.tokenB,D>0?d.tokenB:d.tokenA,D,BigInt(P.outputAmount),BigInt(b.swapFee)),L=(0,y.merge)(d.utxo.assets,W);if(f=f.payToAddress({address:d.utxo.address,assets:L,datum:q}),f=f.collectFrom({inputs:[d.utxo],redeemer:H(d.utxo,i,A,U)}),d.tokenA.unit===x&&r>d.datum.lastWithdrawEpoch&&u[c]){let C=await this.getRewardAmount(t,n,u[c]);f=f.withdraw({stakeCredential:(0,$.fromScript)(u[c].scriptRef),amount:C,redeemer:H(d.utxo,i,A,U)})}}f=f.attachMetadata({label:674n,metadata:new Map([["msg",["Danogo Multi-Pool Swap"]]])}),f.setValidity({from:BigInt(Date.now()-12e4),to:BigInt(Date.now()+24e4)});let v=await(await(await f.build({scriptDataFormat:"array"})).sign()).submit();return(0,it.toHex)(v.hash)}getPoolsFromOgmiosTx(t,e,n){let r=X(e),i=n??r.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,p)=>{let m=a.value,l=m[i];if(l&&a.datum){for(let[b,w]of Object.entries(l))if(w===1n){let u=n+b,A=`${t.id}#${p}`,I=m.ada.lovelace,h=et(m),g=Y(a.datum),R=g.tokenX,T=g.tokenY,f=B=>{if(B===x)return I;let U=B.slice(0,56),k=B.slice(56),v=h.find(c=>c.policyId===U)?.assets.find(c=>c.name===k);return v?v.value:0n};s.push({outRef:A,address:a.address,coin:I,multiAssets:h,validityNft:u,tokenA:R,tokenAReserve:f(R),tokenB:T,tokenBReserve:f(T),lpFeeRate:g.lpFeeRate,priceLowerNum:g.sqrtLowerPriceNum,priceLowerDen:g.sqrtLowerPriceDen,priceUpperNum:g.sqrtUpperPriceNum,priceUpperDen:g.sqrtUpperPriceDen,platformFeeA:g.platformFeeX,platformFeeB:g.platformFeeY,minAChange:g.minXChange,minBChange:g.minYChange,lpTokenTotalSupply:g.circulatingLPToken,lastWithdrawEpoch:g.lastWithdrawEpoch,totalSwapFee:g.totalSwapFee})}}}),s}async getUserTokenBalance(t,e){return(await t.getWalletUtxos()).reduce((r,i)=>r+(e.unit===x?i.assets.lovelace:(0,y.quantityOf)(i.assets,e.policyId,e.assetName)||0n),0n)}buildDeltaAssets(t,e,n,r,i){let s=n>0n?n:-n,a;if(t.unit===x?a=(0,y.fromLovelace)(s+i):a=(0,y.fromAsset)(t.policyId,t.assetName,s,i),e.unit===x)a=(0,y.subtractLovelace)(a,r);else{let p=(0,y.fromAsset)(e.policyId,e.assetName,-r);a=(0,y.merge)(a,p)}return a}async getRewardAmount(t,e,n){let r=new Z.RewardAccount.RewardAccount({networkId:e,stakeCredential:(0,$.fromScript)(n.scriptRef)}),i=Z.RewardAccount.toBech32(r);return(await t.getDelegation(i)).rewards}},Bt=J;
|
|
1
|
+
var M=Object.defineProperty;var nt=Object.getOwnPropertyDescriptor;var rt=Object.getOwnPropertyNames;var it=Object.prototype.hasOwnProperty;var st=(e,o)=>{for(var t in o)M(e,t,{get:o[t],enumerable:!0})},at=(e,o,t,n)=>{if(o&&typeof o=="object"||typeof o=="function")for(let r of rt(o))!it.call(e,r)&&r!==t&&M(e,r,{get:()=>o[r],enumerable:!(n=nt(o,r))||n.enumerable});return e};var ct=e=>at(M({},"__esModule",{value:!0}),e);var bt={};st(bt,{default:()=>It});module.exports=ct(bt);var j=require("@evolution-sdk/evolution"),X=require("@evolution-sdk/evolution/ScriptHash"),b=require("@evolution-sdk/evolution/Assets");function C(e,o){let n=(e>=0n?e:e+(1n<<256n)).toString(16);n.length%2&&(n="0"+n);let r=n.length/2;if(r>o)throw new Error(`Number ${e} requires ${r} bytes, but target length is ${o}.`);let i=new Uint8Array(o),s=o-r;for(let a=0;a<r;a++)i[a+s]=parseInt(n.slice(a*2,a*2+2),16);return i}var v=(e,o,t,n)=>{try{let r=(i,s)=>{let a=3n,g=C(e?i:n,1),d=C(a,1),p=o.map((w,h)=>{let m=s.find(R=>R.utxo.transactionId===w.transactionId&&R.utxo.index===w.index);if(!m)throw new Error(`Pool UTxO at ${h} not found in indexedInputs`);if(t[h]===void 0)throw new Error(`deltaAmount for poolOutIdx ${h} is undefined`);let f=C(BigInt(m.index),1),O=C(BigInt(h),1),U=C(t[h],32);return{poolInBytes:f,poolOutBytes:O,amountBytes:U}}),I=2+34*p.length,x=new Uint8Array(I),c=0;x.set(g,c),c+=g.length,x.set(d,c),c+=d.length;for(let w of p)x.set(w.poolInBytes,c),c+=w.poolInBytes.length,x.set(w.poolOutBytes,c),c+=w.poolOutBytes.length,x.set(w.amountBytes,c),c+=w.amountBytes.length;return x};return{all:i=>{if(!i.length)throw new Error("swapTokensRedeemer batch all called with empty indexedInputs");let s=null;if(e&&(s=i.find(a=>a.utxo.transactionId===e.transactionId&&a.utxo.index===e.index),!s))throw new Error("Target pool UTxO is not found in poolInUTxOs");return r(s?.index,i)},inputs:o}}catch(r){throw console.error("Error creating pool redeemer:",r),r}};var T=require("@evolution-sdk/evolution"),Q=require("@evolution-sdk/evolution/InlineDatum");var A="lovelace";var lt="64d111b957e7d7848ffdde5149aa77fa4090a7fa1ad0ac108067900614848501#0",ut="d8b69fc53637bcfadbc4469083f706bc293f4d9d2296646c5ca167bb",pt="2cafd7c92f7093e5229af274be83dea660b0590b4174bbed79ba662b44fbd1ee#0";var mt="2e19cca74e3badcab26aef7574aa1885ba97228a254ca227ba2f79f2b75fd136#0",ft="04041c3c6ba87b33f2c9eb7f7dbeae3b26003c3e199d438bb99932a2",gt="3775af36f485f9c97101ee5b9b360c34f0f8e12186bc9060f358b7fc8ce468a4#0",q=e=>e===1?{poolScriptOutRef:lt,poolScriptHash:ut,protocolScriptOutRef:pt}:{poolScriptOutRef:mt,poolScriptHash:ft,protocolScriptOutRef:gt};var z=e=>{let o=[new Uint8Array(Buffer.from(e.tokenX.slice(0,56),"hex")),new Uint8Array(Buffer.from(e.tokenX.slice(57),"hex"))],t=[new Uint8Array(Buffer.from(e.tokenY.slice(0,56),"hex")),new Uint8Array(Buffer.from(e.tokenY.slice(57),"hex"))],n=T.Data.constr(0n,[e.sqrtLowerPriceNum,e.sqrtLowerPriceDen]),r=T.Data.constr(0n,[e.sqrtUpperPriceNum,e.sqrtUpperPriceDen]),i=T.Data.constr(0n,[o,t,BigInt(e.lpFeeRate),e.platformFeeX,e.platformFeeY,e.totalSwapFee,n,r,e.minXChange,e.minYChange,e.circulatingLPToken,BigInt(e.lastWithdrawEpoch)]);return new Q.InlineDatum({data:i})};var L=e=>{let o;if(typeof e=="string")o=T.CBOR.fromCBORHex(e);else{let i=e.data,s=T.Data.toCBORHex(i);o=T.CBOR.fromCBORHex(s)}let t=o._tag==="Tag"?o.value:o;if(!Array.isArray(t))throw new Error("Invalid datum structure: expected array of fields");let n=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]),g=s[1]instanceof Uint8Array?s[1]:new Uint8Array(s[1]),d=Buffer.from(a).toString("hex"),p=Buffer.from(g).toString("hex");return d===""&&p===""?A:d+"."+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:n(t[0]),tokenY:n(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])}},$=e=>{let o,t=T.Data.toCBORHex(e.data);o=T.CBOR.fromCBORHex(t);let n=o._tag==="Tag"?o.value:o;if(!Array.isArray(n))throw new Error("Invalid datum structure: expected array of fields");return{platformFeeRate:BigInt(n[0]),swapFee:BigInt(n[1])}};var E=require("@evolution-sdk/evolution");function k(e){if(e===A)return{unit:A};let o=e.indexOf("."),t=o===-1?e:e.slice(0,o),n=o===-1?"":e.slice(o+1),r=E.Bytes.fromHex(t),i=new E.PolicyId.PolicyId({hash:r}),s=n?E.Bytes.fromHex(n):new Uint8Array(0),a=new E.AssetName.AssetName({bytes:s});return{policyId:i,assetName:a,unit:e}}var J=e=>{if(!e||Object.keys(e).length===0)return[];let o=[];for(let[t,n]of Object.entries(e)){if(t==="ada")continue;let r=[];for(let[i,s]of Object.entries(n))r.push({name:i,value:s});o.push({policyId:t,assets:r})}return o};var H=require("@evolution-sdk/evolution");var W=(e,o)=>{let t=432e6,n=1647899091e3,r=328;return o!==1&&(t=18e5),Math.floor((e-n)/t)+r};function xt(e,o,t,n,r=0n,i){let s=n<0n?-n:n,a=t.tokenX===A?3000000n+BigInt(t.totalSwapFee):0n,g=BigInt(e)-BigInt(t.platformFeeX)+r-a,d=BigInt(o)-BigInt(t.platformFeeY),p=ht(g,d,[BigInt(t.sqrtLowerPriceNum),BigInt(t.sqrtLowerPriceDen)],[BigInt(t.sqrtUpperPriceNum),BigInt(t.sqrtUpperPriceDen)]),I=Z(p[0]*BigInt(t.sqrtUpperPriceDen),p[1]*BigInt(t.sqrtUpperPriceNum))+g,x=Z(p[0]*BigInt(t.sqrtLowerPriceNum),p[1]*BigInt(t.sqrtLowerPriceDen))+d;return n>0n?K(s,I,x,d,BigInt(t.lpFeeRate),i):K(s,x,I,g,BigInt(t.lpFeeRate),i)}var K=(e,o,t,n,r,i)=>{let s=10000n,g=e*r/s*BigInt(i)/10000n,d=s-r,p=o*s+e*d,I=o*t,c=(t*p-I*s)/p;if(c>n)throw new Error("pool out exceeded");return[c,g]},ht=(e,o,t,n)=>{let r=t[1]*n[1],i=t[0]*n[0],s=(o*r-e*i)*(o*r-e*i),a=4n*e*o*t[1]*t[1]*n[0]*n[0],g=At(s+a),d=o*r+e*i+g,p=2n*(n[0]*t[1]-n[1]*t[0]);return[d,p]};function At(e){if(e<0n)throw new Error("Square root of negative number");if(e<2n)return e;let o=e,t=o+e/o>>1n;for(;t<o;)o=t,t=o+e/o>>1n;return o}function Z(e,o){if(o===0n)throw new Error("Division by zero");let t=e/o;return e%o===0n||e<0n!=o<0n?t:t+1n}function tt(e,o){let n=[...o].sort((r,i)=>r.transactionId===i.transactionId?r.index<i.index?-1:1:r.transactionId<i.transactionId?-1:1).findIndex(r=>r.transactionId===e.transactionId&&r.index===e.index);if(n===-1)throw new Error("Protocol config out ref not found in reference inputs");return BigInt(n)}function G(e,o,t){let n=[];for(let r=0;r<e.length;r++){let i=e[r],s=o[r];if(s===0n)continue;let[a,g]=xt(i.tokenAAmount,i.tokenBAmount,i.datum,s,i.rewardAmount,t);n.push({poolIndex:r,deltaAmount:s,outputAmount:a,platformFee:g})}return n}var ot=e=>{if(!e)return;let[o,t]=e.split("#");return new H.TransactionInput.TransactionInput({transactionId:H.TransactionHash.fromHex(o),index:BigInt(t)})};var et=require("@evolution-sdk/evolution/Bytes32"),V=class{constructor(){}async calculateSwapOut(o,t){if(!o||!o.address)throw new Error("Please connect a wallet first.");let n=(await o.address()).networkId,r=W(Date.now(),n),i=await Promise.all(t.pools.map(c=>this.getUtxoOrThrow(o,c.poolOutRef,"Pool input"))),s=q(n),a=t.protocolConfigOutRef??s.protocolScriptOutRef,g=await this.getUtxoOrThrow(o,a,"Protocol config");if(!g.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let d=$(g.datumOption),p=await Promise.all(t.pools.map(async(c,w)=>{let h=i[w];if(!h.datumOption)throw new Error(`Pool input UTxO ${w} does not contain a datum.`);let m=L(h.datumOption),f=k(m.tokenX),O=k(m.tokenY),U=h.assets.lovelace,R=u=>u.unit===A?U:(0,b.quantityOf)(h.assets,u.policyId,u.assetName),B=null;c.stakingOutRef&&(B=await this.getUtxoOrThrow(o,c.stakingOutRef,"Staking"));let l=0n;return f.unit===A&&B&&r>m.lastWithdrawEpoch&&(l=await this.getRewardAmount(o,n,B)),{tokenAAmount:R(f),tokenBAmount:R(O),datum:m,rewardAmount:l}})),I=t.pools.map(c=>c.deltaAmount);return G(p,I,d.platformFeeRate).map(c=>c.outputAmount)}async submitSwap(o,t){if(!o||!o.address)throw new Error("Please connect a wallet first.");let n=(await o.address()).networkId,r=W(Date.now(),n),i=await Promise.all(t.pools.map(l=>this.getUtxoOrThrow(o,l.poolOutRef,"Pool input"))),s=q(n),a=s.poolScriptOutRef,g=t.protocolConfigOutRef??s.protocolScriptOutRef,d=await this.getUtxoOrThrow(o,a,"Pool script"),p=await this.getUtxoOrThrow(o,g,"Protocol config");if(!p.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let I=$(p.datumOption),x=[],c=[];for(let l=0;l<t.pools.length;l++){let u=t.pools[l],y=i[l];if(!y.datumOption)throw new Error(`Pool input UTxO ${l} does not contain a datum.`);let P=L(y.datumOption),D=k(P.tokenX),F=k(P.tokenY),Y=y.assets.lovelace,S=N=>N.unit===A?Y:(0,b.quantityOf)(y.assets,N.policyId,N.assetName),_=null;u.stakingOutRef&&(_=await this.getUtxoOrThrow(o,u.stakingOutRef,"Staking")),c.push(_),x.push({tokenAAmount:S(D),tokenBAmount:S(F),datum:P,utxo:y,tokenA:D,tokenB:F})}let w=t.pools.map(l=>l.deltaAmount),h=G(x,w,I.platformFeeRate);h.forEach((l,u)=>{let y=t.pools[u].minOutChangeAmount??0n;if(l.outputAmount<y)throw new Error(`Expected swap output at least ${y} but got ${l.outputAmount}`)});let m=o.newTx(),f=[p];f.push(d),c.forEach(l=>{l&&f.push(l)}),m=m.readFrom({referenceInputs:f});let O=tt(p,f);m=m.withdraw({stakeCredential:(0,X.fromScript)(d.scriptRef),amount:0n,redeemer:v(null,i,w,O)});for(let l=0;l<x.length;l++){let u=x[l],y=h.find(N=>N.poolIndex===l);if(!y)continue;let{deltaAmount:P,platformFee:D,outputAmount:F}=y,Y=z({...u.datum,platformFeeX:BigInt(u.datum.platformFeeX)+(P>0?D:0n),platformFeeY:BigInt(u.datum.platformFeeY)+(P<0?D:0n),lastWithdrawEpoch:r,totalSwapFee:BigInt(u.datum.totalSwapFee)+I.swapFee}),S=this.buildDeltaAssets(P>0?u.tokenA:u.tokenB,P>0?u.tokenB:u.tokenA,P,F,I.swapFee),_=(0,b.merge)(u.utxo.assets,S);if(m=m.payToAddress({address:u.utxo.address,assets:_,datum:Y}),m=m.collectFrom({inputs:[u.utxo],redeemer:v(u.utxo,i,w,O)}),u.tokenA.unit===A&&r>u.datum.lastWithdrawEpoch&&c[l]){let N=await this.getRewardAmount(o,n,c[l]);m=m.withdraw({stakeCredential:(0,X.fromScript)(c[l].scriptRef),amount:N,redeemer:v(u.utxo,i,w,O)})}}m=m.attachMetadata({label:674n,metadata:new Map([["msg",["Danogo Multi-Pool Swap"]]])}),m.setValidity({from:BigInt(Date.now()-12e4),to:BigInt(Date.now()+24e4)});let B=await(await(await m.build({scriptDataFormat:"array"})).sign()).submit();return(0,et.toHex)(B.hash)}getPoolsFromOgmiosTx(o,t,n){let r=q(t),i=n??r.poolScriptHash;if(!i)throw new Error("Pool script hash is required but not provided or not found for this network.");let s=[];return o.outputs.forEach((a,g)=>{let d=a.value,p=d[i];if(p&&a.datum){for(let[I,x]of Object.entries(p))if(x===1n){let c=n+I,w=`${o.id}#${g}`,h=d.ada.lovelace,m=J(d),f=L(a.datum),O=f.tokenX,U=f.tokenY,R=B=>{if(B===A)return h;let l=B.slice(0,56),u=B.slice(56),P=m.find(D=>D.policyId===l)?.assets.find(D=>D.name===u);return P?P.value:0n};s.push({outRef:w,address:a.address,coin:h,multiAssets:m,validityNft:c,tokenA:O,tokenAReserve:R(O),tokenB:U,tokenBReserve:R(U),lpFeeRate:f.lpFeeRate,priceLowerNum:f.sqrtLowerPriceNum,priceLowerDen:f.sqrtLowerPriceDen,priceUpperNum:f.sqrtUpperPriceNum,priceUpperDen:f.sqrtUpperPriceDen,platformFeeA:f.platformFeeX,platformFeeB:f.platformFeeY,minAChange:f.minXChange,minBChange:f.minYChange,lpTokenTotalSupply:f.circulatingLPToken,lastWithdrawEpoch:f.lastWithdrawEpoch,totalSwapFee:f.totalSwapFee})}}}),s}async getUserTokenBalance(o,t){return(await o.getWalletUtxos()).reduce((r,i)=>r+(t.unit===A?i.assets.lovelace:(0,b.quantityOf)(i.assets,t.policyId,t.assetName)||0n),0n)}buildDeltaAssets(o,t,n,r,i){let s=n>0n?n:-n,a;if(o.unit===A?a=(0,b.fromLovelace)(s+i):a=(0,b.fromAsset)(o.policyId,o.assetName,s,i),t.unit===A)a=(0,b.subtractLovelace)(a,r);else{let g=(0,b.fromAsset)(t.policyId,t.assetName,-r);a=(0,b.merge)(a,g)}return a}async getRewardAmount(o,t,n){let r=new j.RewardAccount.RewardAccount({networkId:t,stakeCredential:(0,X.fromScript)(n.scriptRef)}),i=j.RewardAccount.toBech32(r);return(await o.getDelegation(i)).rewards}async getUtxoOrThrow(o,t,n){let r=ot(t);if(!r)throw new Error(`Invalid ${n} output reference: ${t}`);let i=await o.getUtxosByOutRef([r]);if(!i||i.length===0)throw new Error(`${n} ${t} UTxO not found or spent.`);return i[0]}},It=V;
|
package/dist/sdk.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{RewardAccount as ot}from"@evolution-sdk/evolution";import{fromScript as j}from"@evolution-sdk/evolution/ScriptHash";import{fromAsset as nt,merge as rt,quantityOf as V,fromLovelace as ht,subtractLovelace as Pt}from"@evolution-sdk/evolution/Assets";function k(o,e){let n=(o>=0n?o:o+(1n<<256n)).toString(16);n.length%2&&(n="0"+n);let i=n.length/2;if(i>e)throw new Error(`Number ${o} requires ${i} bytes, but target length is ${e}.`);let r=new Uint8Array(e),s=e-i;for(let a=0;a<i;a++)r[a+s]=parseInt(n.slice(a*2,a*2+2),16);return r}var q=(o,e,t,n)=>{try{let i=(r,s)=>{let a=3n,p=k(o?r:n,1),m=k(a,1),l=e.map((A,I)=>{let y=s.find(f=>f.utxo.transactionId===A.transactionId&&f.utxo.index===A.index);if(!y)throw new Error(`Pool UTxO at ${I} not found in indexedInputs`);if(t[I]===void 0)throw new Error(`deltaAmount for poolOutIdx ${I} is undefined`);let g=k(BigInt(y.index),1),B=k(BigInt(I),1),O=k(t[I],32);return{poolInBytes:g,poolOutBytes:B,amountBytes:O}}),b=2+34*l.length,w=new Uint8Array(b),u=0;w.set(p,u),u+=p.length,w.set(m,u),u+=m.length;for(let A of l)w.set(A.poolInBytes,u),u+=A.poolInBytes.length,w.set(A.poolOutBytes,u),u+=A.poolOutBytes.length,w.set(A.amountBytes,u),u+=A.amountBytes.length;return w};return{all:r=>{if(!r.length)throw new Error("swapTokensRedeemer batch all called with empty indexedInputs");let s=null;if(o&&(s=r.find(a=>a.utxo.transactionId===o.transactionId&&a.utxo.index===o.index),!s))throw new Error("Target pool UTxO is not found in poolInUTxOs");return i(s?.index,r)},inputs:e}}catch(i){throw console.error("Error creating pool redeemer:",i),i}};import{Data as C,CBOR as M}from"@evolution-sdk/evolution";import{InlineDatum as ft}from"@evolution-sdk/evolution/InlineDatum";var x="lovelace";var st="64d111b957e7d7848ffdde5149aa77fa4090a7fa1ad0ac108067900614848501#0",at="d8b69fc53637bcfadbc4469083f706bc293f4d9d2296646c5ca167bb",ct="2cafd7c92f7093e5229af274be83dea660b0590b4174bbed79ba662b44fbd1ee#0";var ut="2e19cca74e3badcab26aef7574aa1885ba97228a254ca227ba2f79f2b75fd136#0",lt="04041c3c6ba87b33f2c9eb7f7dbeae3b26003c3e199d438bb99932a2",pt="3775af36f485f9c97101ee5b9b360c34f0f8e12186bc9060f358b7fc8ce468a4#0",L=o=>o===1?{poolScriptOutRef:st,poolScriptHash:at,protocolScriptOutRef:ct}:{poolScriptOutRef:ut,poolScriptHash:lt,protocolScriptOutRef:pt};var Q=o=>{let e=[new Uint8Array(Buffer.from(o.tokenX.slice(0,56),"hex")),new Uint8Array(Buffer.from(o.tokenX.slice(57),"hex"))],t=[new Uint8Array(Buffer.from(o.tokenY.slice(0,56),"hex")),new Uint8Array(Buffer.from(o.tokenY.slice(57),"hex"))],n=C.constr(0n,[o.sqrtLowerPriceNum,o.sqrtLowerPriceDen]),i=C.constr(0n,[o.sqrtUpperPriceNum,o.sqrtUpperPriceDen]),r=C.constr(0n,[e,t,BigInt(o.lpFeeRate),o.platformFeeX,o.platformFeeY,o.totalSwapFee,n,i,o.minXChange,o.minYChange,o.circulatingLPToken,BigInt(o.lastWithdrawEpoch)]);return new ft({data:r})};var H=o=>{let e;if(typeof o=="string")e=M.fromCBORHex(o);else{let r=o.data,s=C.toCBORHex(r);e=M.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 n=r=>{let s=r._tag==="Tag"?r.value:r;if(Array.isArray(s)&&s.length===2){let a=s[0]instanceof Uint8Array?s[0]:new Uint8Array(s[0]),p=s[1]instanceof Uint8Array?s[1]:new Uint8Array(s[1]),m=Buffer.from(a).toString("hex"),l=Buffer.from(p).toString("hex");return m===""&&l===""?x:m+"."+l}throw new Error("Invalid AssetClass structure")},i=r=>{let s=r._tag==="Tag"?r.value:r;if(Array.isArray(s)&&s.length===2)return{num:BigInt(s[0]),den:BigInt(s[1])};throw new Error("Invalid Ratio structure")};return{tokenX:n(t[0]),tokenY:n(t[1]),lpFeeRate:Number(t[2]),platformFeeX:BigInt(t[3]),platformFeeY:BigInt(t[4]),totalSwapFee:BigInt(t[5]),sqrtLowerPriceNum:i(t[6]).num,sqrtLowerPriceDen:i(t[6]).den,sqrtUpperPriceNum:i(t[7]).num,sqrtUpperPriceDen:i(t[7]).den,minXChange:BigInt(t[8]),minYChange:BigInt(t[9]),circulatingLPToken:BigInt(t[10]),lastWithdrawEpoch:Number(t[11])}},$=o=>{let e,t=C.toCBORHex(o.data);e=M.fromCBORHex(t);let n=e._tag==="Tag"?e.value:e;if(!Array.isArray(n))throw new Error("Invalid datum structure: expected array of fields");return{platformFeeRate:BigInt(n[0]),swapFee:BigInt(n[1])}};import{AssetName as mt,Bytes as Z,PolicyId as gt}from"@evolution-sdk/evolution";function F(o){if(o===x)return{unit:x};let e=o.indexOf("."),t=e===-1?o:o.slice(0,e),n=e===-1?"":o.slice(e+1),i=Z.fromHex(t),r=new gt.PolicyId({hash:i}),s=n?Z.fromHex(n):new Uint8Array(0),a=new mt.AssetName({bytes:s});return{policyId:r,assetName:a,unit:o}}var J=o=>{if(!o||Object.keys(o).length===0)return[];let e=[];for(let[t,n]of Object.entries(o)){if(t==="ada")continue;let i=[];for(let[r,s]of Object.entries(n))i.push({name:r,value:s});e.push({policyId:t,assets:i})}return e};import{TransactionHash as At,TransactionInput as It}from"@evolution-sdk/evolution";var W=(o,e)=>{let t=432e6,n=1647899091e3,i=328;return e!==1&&(t=18e5),Math.floor((o-n)/t)+i};function xt(o,e,t,n,i=0n,r){let s=n<0n?-n:n,a=t.tokenX===x?3000000n+BigInt(t.totalSwapFee):0n,p=BigInt(o)-BigInt(t.platformFeeX)+i-a,m=BigInt(e)-BigInt(t.platformFeeY),l=bt(p,m,[BigInt(t.sqrtLowerPriceNum),BigInt(t.sqrtLowerPriceDen)],[BigInt(t.sqrtUpperPriceNum),BigInt(t.sqrtUpperPriceDen)]),b=tt(l[0]*BigInt(t.sqrtUpperPriceDen),l[1]*BigInt(t.sqrtUpperPriceNum))+p,w=tt(l[0]*BigInt(t.sqrtLowerPriceNum),l[1]*BigInt(t.sqrtLowerPriceDen))+m;return n>0n?K(s,b,w,m,BigInt(t.lpFeeRate),r):K(s,w,b,p,BigInt(t.lpFeeRate),r)}var K=(o,e,t,n,i,r)=>{let s=10000n,p=o*i/s*BigInt(r)/10000n,m=s-i,l=e*s+o*m,b=e*t,u=(t*l-b*s)/l;if(u>n)throw new Error("pool out exceeded");return[u,p]},bt=(o,e,t,n)=>{let i=t[1]*n[1],r=t[0]*n[0],s=(e*i-o*r)*(e*i-o*r),a=4n*o*e*t[1]*t[1]*n[0]*n[0],p=yt(s+a),m=e*i+o*r+p,l=2n*(n[0]*t[1]-n[1]*t[0]);return[m,l]};function yt(o){if(o<0n)throw new Error("Square root of negative number");if(o<2n)return o;let e=o,t=e+o/e>>1n;for(;t<e;)e=t,t=e+o/e>>1n;return e}function tt(o,e){if(e===0n)throw new Error("Division by zero");let t=o/e;return o%e===0n||o<0n!=e<0n?t:t+1n}function et(o,e){let n=[...e].sort((i,r)=>i.transactionId===r.transactionId?i.index<r.index?-1:1:i.transactionId<r.transactionId?-1:1).findIndex(i=>i.transactionId===o.transactionId&&i.index===o.index);if(n===-1)throw new Error("Protocol config out ref not found in reference inputs");return BigInt(n)}function G(o,e,t){let n=[];for(let i=0;i<o.length;i++){let r=o[i],s=e[i];if(s===0n)continue;let[a,p]=xt(r.tokenAAmount,r.tokenBAmount,r.datum,s,r.rewardAmount,t);n.push({poolIndex:i,deltaAmount:s,outputAmount:a,platformFee:p})}return n}var D=o=>{if(!o)return;let[e,t]=o.split("#");return new It.TransactionInput({transactionId:At.fromHex(e),index:BigInt(t)})};import{toHex as Bt}from"@evolution-sdk/evolution/Bytes32";var z=class{constructor(){}async calculateSwapOut(e,t){if(!e||!e.address)throw new Error("Please connect a wallet first.");let n=(await e.address()).networkId,i=W(Date.now(),n),r=await Promise.all(t.pools.map(u=>e.getUtxosByOutRef([D(u.poolOutRef)]))),s=L(n),a=t.protocolConfigOutRef??s.protocolScriptOutRef,p=(await e.getUtxosByOutRef([D(a)]))[0];if(!p.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let m=$(p.datumOption),l=await Promise.all(t.pools.map(async(u,A)=>{let I=r[A][0];if(!I.datumOption)throw new Error(`Pool input UTxO ${A} does not contain a datum.`);let y=H(I.datumOption),g=F(y.tokenX),B=F(y.tokenY),O=I.assets.lovelace,f=U=>U.unit===x?O:V(I.assets,U.policyId,U.assetName),P=null;u.stakingOutRef&&(P=(await e.getUtxosByOutRef([D(u.stakingOutRef)]))[0]);let T=0n;return g.unit===x&&P&&i>y.lastWithdrawEpoch&&(T=await this.getRewardAmount(e,n,P)),{tokenAAmount:f(g),tokenBAmount:f(B),datum:y,rewardAmount:T}})),b=t.pools.map(u=>u.deltaAmount);return G(l,b,m.platformFeeRate).map(u=>u.outputAmount)}async submitSwap(e,t){if(!e||!e.address)throw new Error("Please connect a wallet first.");let n=(await e.address()).networkId,i=W(Date.now(),n),r=await Promise.all(t.pools.map(async c=>(await e.getUtxosByOutRef([D(c.poolOutRef)]))[0])),s=L(n),a=s.poolScriptOutRef,p=t.protocolConfigOutRef??s.protocolScriptOutRef,m=(await e.getUtxosByOutRef([D(a)]))[0],l=(await e.getUtxosByOutRef([D(p)]))[0];if(!l.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let b=$(l.datumOption),w=[],u=[];for(let c=0;c<t.pools.length;c++){let d=t.pools[c],h=r[c];if(!h.datumOption)throw new Error(`Pool input UTxO ${c} does not contain a datum.`);let R=H(h.datumOption),E=F(R.tokenX),_=F(R.tokenY),X=h.assets.lovelace,v=Y=>Y.unit===x?X:V(h.assets,Y.policyId,Y.assetName),N=null;d.stakingOutRef&&(N=(await e.getUtxosByOutRef([D(d.stakingOutRef)]))[0]),u.push(N),w.push({tokenAAmount:v(E),tokenBAmount:v(_),datum:R,utxo:h,tokenA:E,tokenB:_})}let A=t.pools.map(c=>c.deltaAmount),I=G(w,A,b.platformFeeRate);I.forEach((c,d)=>{let h=t.pools[d].minOutChangeAmount;if(c.outputAmount<h)throw new Error(`Expected swap output at least ${h} but got ${c.outputAmount}`)});let y=I.reduce((c,d)=>c+d.deltaAmount,0n),g=t.pools.find(c=>c.deltaAmount!==0n);if(!g)throw new Error("At least one pool must have a non-zero delta amount");let B=g.deltaAmount>0?w[0].tokenA:w[0].tokenB,O=await this.getUserTokenBalance(e,B);if(O<y)throw new Error(`Insufficient ${B.unit} balance. Required: ${y}, Available: ${O}`);let f=e.newTx(),P=[l];P.push(m),u.forEach(c=>{c&&P.push(c)}),f=f.readFrom({referenceInputs:P});let T=et(l,P);f=f.withdraw({stakeCredential:j(m.scriptRef),amount:0n,redeemer:q(null,r,A,T)});for(let c=0;c<w.length;c++){let d=w[c],h=I.find(N=>N.poolIndex===c);if(!h)continue;let R=h.deltaAmount,E=h.platformFee,_=Q({...d.datum,platformFeeX:BigInt(d.datum.platformFeeX)+(R>0?E:0n),platformFeeY:BigInt(d.datum.platformFeeY)+(R<0?E:0n),lastWithdrawEpoch:i,totalSwapFee:BigInt(d.datum.totalSwapFee)+BigInt(b.swapFee)}),X=this.buildDeltaAssets(R>0?d.tokenA:d.tokenB,R>0?d.tokenB:d.tokenA,R,BigInt(h.outputAmount),BigInt(b.swapFee)),v=rt(d.utxo.assets,X);if(f=f.payToAddress({address:d.utxo.address,assets:v,datum:_}),f=f.collectFrom({inputs:[d.utxo],redeemer:q(d.utxo,r,A,T)}),d.tokenA.unit===x&&i>d.datum.lastWithdrawEpoch&&u[c]){let N=await this.getRewardAmount(e,n,u[c]);f=f.withdraw({stakeCredential:j(u[c].scriptRef),amount:N,redeemer:q(d.utxo,r,A,T)})}}f=f.attachMetadata({label:674n,metadata:new Map([["msg",["Danogo Multi-Pool Swap"]]])}),f.setValidity({from:BigInt(Date.now()-12e4),to:BigInt(Date.now()+24e4)});let S=await(await(await f.build({scriptDataFormat:"array"})).sign()).submit();return Bt(S.hash)}getPoolsFromOgmiosTx(e,t,n){let i=L(t),r=n??i.poolScriptHash;if(!r)throw new Error("Pool script hash is required but not provided or not found for this network.");let s=[];return e.outputs.forEach((a,p)=>{let m=a.value,l=m[r];if(l&&a.datum){for(let[b,w]of Object.entries(l))if(w===1n){let u=n+b,A=`${e.id}#${p}`,I=m.ada.lovelace,y=J(m),g=H(a.datum),B=g.tokenX,O=g.tokenY,f=P=>{if(P===x)return I;let T=P.slice(0,56),U=P.slice(56),S=y.find(c=>c.policyId===T)?.assets.find(c=>c.name===U);return S?S.value:0n};s.push({outRef:A,address:a.address,coin:I,multiAssets:y,validityNft:u,tokenA:B,tokenAReserve:f(B),tokenB:O,tokenBReserve:f(O),lpFeeRate:g.lpFeeRate,priceLowerNum:g.sqrtLowerPriceNum,priceLowerDen:g.sqrtLowerPriceDen,priceUpperNum:g.sqrtUpperPriceNum,priceUpperDen:g.sqrtUpperPriceDen,platformFeeA:g.platformFeeX,platformFeeB:g.platformFeeY,minAChange:g.minXChange,minBChange:g.minYChange,lpTokenTotalSupply:g.circulatingLPToken,lastWithdrawEpoch:g.lastWithdrawEpoch,totalSwapFee:g.totalSwapFee})}}}),s}async getUserTokenBalance(e,t){return(await e.getWalletUtxos()).reduce((i,r)=>i+(t.unit===x?r.assets.lovelace:V(r.assets,t.policyId,t.assetName)||0n),0n)}buildDeltaAssets(e,t,n,i,r){let s=n>0n?n:-n,a;if(e.unit===x?a=ht(s+r):a=nt(e.policyId,e.assetName,s,r),t.unit===x)a=Pt(a,i);else{let p=nt(t.policyId,t.assetName,-i);a=rt(a,p)}return a}async getRewardAmount(e,t,n){let i=new ot.RewardAccount({networkId:t,stakeCredential:j(n.scriptRef)}),r=ot.toBech32(i);return(await e.getDelegation(r)).rewards}},Kt=z;export{Kt as default};
|
|
1
|
+
import{RewardAccount as Z}from"@evolution-sdk/evolution";import{fromScript as M}from"@evolution-sdk/evolution/ScriptHash";import{fromAsset as tt,merge as ot,quantityOf as $,fromLovelace as ht,subtractLovelace as At}from"@evolution-sdk/evolution/Assets";function U(e,o){let n=(e>=0n?e:e+(1n<<256n)).toString(16);n.length%2&&(n="0"+n);let i=n.length/2;if(i>o)throw new Error(`Number ${e} requires ${i} bytes, but target length is ${o}.`);let r=new Uint8Array(o),s=o-i;for(let a=0;a<i;a++)r[a+s]=parseInt(n.slice(a*2,a*2+2),16);return r}var S=(e,o,t,n)=>{try{let i=(r,s)=>{let a=3n,g=U(e?r:n,1),d=U(a,1),p=o.map((w,h)=>{let m=s.find(O=>O.utxo.transactionId===w.transactionId&&O.utxo.index===w.index);if(!m)throw new Error(`Pool UTxO at ${h} not found in indexedInputs`);if(t[h]===void 0)throw new Error(`deltaAmount for poolOutIdx ${h} is undefined`);let f=U(BigInt(m.index),1),P=U(BigInt(h),1),B=U(t[h],32);return{poolInBytes:f,poolOutBytes:P,amountBytes:B}}),I=2+34*p.length,x=new Uint8Array(I),c=0;x.set(g,c),c+=g.length,x.set(d,c),c+=d.length;for(let w of p)x.set(w.poolInBytes,c),c+=w.poolInBytes.length,x.set(w.poolOutBytes,c),c+=w.poolOutBytes.length,x.set(w.amountBytes,c),c+=w.amountBytes.length;return x};return{all:r=>{if(!r.length)throw new Error("swapTokensRedeemer batch all called with empty indexedInputs");let s=null;if(e&&(s=r.find(a=>a.utxo.transactionId===e.transactionId&&a.utxo.index===e.index),!s))throw new Error("Target pool UTxO is not found in poolInUTxOs");return i(s?.index,r)},inputs:o}}catch(i){throw console.error("Error creating pool redeemer:",i),i}};import{Data as N,CBOR as L}from"@evolution-sdk/evolution";import{InlineDatum as ct}from"@evolution-sdk/evolution/InlineDatum";var A="lovelace";var et="64d111b957e7d7848ffdde5149aa77fa4090a7fa1ad0ac108067900614848501#0",nt="d8b69fc53637bcfadbc4469083f706bc293f4d9d2296646c5ca167bb",rt="2cafd7c92f7093e5229af274be83dea660b0590b4174bbed79ba662b44fbd1ee#0";var it="2e19cca74e3badcab26aef7574aa1885ba97228a254ca227ba2f79f2b75fd136#0",st="04041c3c6ba87b33f2c9eb7f7dbeae3b26003c3e199d438bb99932a2",at="3775af36f485f9c97101ee5b9b360c34f0f8e12186bc9060f358b7fc8ce468a4#0",_=e=>e===1?{poolScriptOutRef:et,poolScriptHash:nt,protocolScriptOutRef:rt}:{poolScriptOutRef:it,poolScriptHash:st,protocolScriptOutRef:at};var G=e=>{let o=[new Uint8Array(Buffer.from(e.tokenX.slice(0,56),"hex")),new Uint8Array(Buffer.from(e.tokenX.slice(57),"hex"))],t=[new Uint8Array(Buffer.from(e.tokenY.slice(0,56),"hex")),new Uint8Array(Buffer.from(e.tokenY.slice(57),"hex"))],n=N.constr(0n,[e.sqrtLowerPriceNum,e.sqrtLowerPriceDen]),i=N.constr(0n,[e.sqrtUpperPriceNum,e.sqrtUpperPriceDen]),r=N.constr(0n,[o,t,BigInt(e.lpFeeRate),e.platformFeeX,e.platformFeeY,e.totalSwapFee,n,i,e.minXChange,e.minYChange,e.circulatingLPToken,BigInt(e.lastWithdrawEpoch)]);return new ct({data:r})};var v=e=>{let o;if(typeof e=="string")o=L.fromCBORHex(e);else{let r=e.data,s=N.toCBORHex(r);o=L.fromCBORHex(s)}let t=o._tag==="Tag"?o.value:o;if(!Array.isArray(t))throw new Error("Invalid datum structure: expected array of fields");let n=r=>{let s=r._tag==="Tag"?r.value:r;if(Array.isArray(s)&&s.length===2){let a=s[0]instanceof Uint8Array?s[0]:new Uint8Array(s[0]),g=s[1]instanceof Uint8Array?s[1]:new Uint8Array(s[1]),d=Buffer.from(a).toString("hex"),p=Buffer.from(g).toString("hex");return d===""&&p===""?A:d+"."+p}throw new Error("Invalid AssetClass structure")},i=r=>{let s=r._tag==="Tag"?r.value:r;if(Array.isArray(s)&&s.length===2)return{num:BigInt(s[0]),den:BigInt(s[1])};throw new Error("Invalid Ratio structure")};return{tokenX:n(t[0]),tokenY:n(t[1]),lpFeeRate:Number(t[2]),platformFeeX:BigInt(t[3]),platformFeeY:BigInt(t[4]),totalSwapFee:BigInt(t[5]),sqrtLowerPriceNum:i(t[6]).num,sqrtLowerPriceDen:i(t[6]).den,sqrtUpperPriceNum:i(t[7]).num,sqrtUpperPriceDen:i(t[7]).den,minXChange:BigInt(t[8]),minYChange:BigInt(t[9]),circulatingLPToken:BigInt(t[10]),lastWithdrawEpoch:Number(t[11])}},H=e=>{let o,t=N.toCBORHex(e.data);o=L.fromCBORHex(t);let n=o._tag==="Tag"?o.value:o;if(!Array.isArray(n))throw new Error("Invalid datum structure: expected array of fields");return{platformFeeRate:BigInt(n[0]),swapFee:BigInt(n[1])}};import{AssetName as lt,Bytes as j,PolicyId as ut}from"@evolution-sdk/evolution";function E(e){if(e===A)return{unit:A};let o=e.indexOf("."),t=o===-1?e:e.slice(0,o),n=o===-1?"":e.slice(o+1),i=j.fromHex(t),r=new ut.PolicyId({hash:i}),s=n?j.fromHex(n):new Uint8Array(0),a=new lt.AssetName({bytes:s});return{policyId:r,assetName:a,unit:e}}var V=e=>{if(!e||Object.keys(e).length===0)return[];let o=[];for(let[t,n]of Object.entries(e)){if(t==="ada")continue;let i=[];for(let[r,s]of Object.entries(n))i.push({name:r,value:s});o.push({policyId:t,assets:i})}return o};import{TransactionHash as ft,TransactionInput as gt}from"@evolution-sdk/evolution";var X=(e,o)=>{let t=432e6,n=1647899091e3,i=328;return o!==1&&(t=18e5),Math.floor((e-n)/t)+i};function dt(e,o,t,n,i=0n,r){let s=n<0n?-n:n,a=t.tokenX===A?3000000n+BigInt(t.totalSwapFee):0n,g=BigInt(e)-BigInt(t.platformFeeX)+i-a,d=BigInt(o)-BigInt(t.platformFeeY),p=wt(g,d,[BigInt(t.sqrtLowerPriceNum),BigInt(t.sqrtLowerPriceDen)],[BigInt(t.sqrtUpperPriceNum),BigInt(t.sqrtUpperPriceDen)]),I=z(p[0]*BigInt(t.sqrtUpperPriceDen),p[1]*BigInt(t.sqrtUpperPriceNum))+g,x=z(p[0]*BigInt(t.sqrtLowerPriceNum),p[1]*BigInt(t.sqrtLowerPriceDen))+d;return n>0n?Q(s,I,x,d,BigInt(t.lpFeeRate),r):Q(s,x,I,g,BigInt(t.lpFeeRate),r)}var Q=(e,o,t,n,i,r)=>{let s=10000n,g=e*i/s*BigInt(r)/10000n,d=s-i,p=o*s+e*d,I=o*t,c=(t*p-I*s)/p;if(c>n)throw new Error("pool out exceeded");return[c,g]},wt=(e,o,t,n)=>{let i=t[1]*n[1],r=t[0]*n[0],s=(o*i-e*r)*(o*i-e*r),a=4n*e*o*t[1]*t[1]*n[0]*n[0],g=xt(s+a),d=o*i+e*r+g,p=2n*(n[0]*t[1]-n[1]*t[0]);return[d,p]};function xt(e){if(e<0n)throw new Error("Square root of negative number");if(e<2n)return e;let o=e,t=o+e/o>>1n;for(;t<o;)o=t,t=o+e/o>>1n;return o}function z(e,o){if(o===0n)throw new Error("Division by zero");let t=e/o;return e%o===0n||e<0n!=o<0n?t:t+1n}function J(e,o){let n=[...o].sort((i,r)=>i.transactionId===r.transactionId?i.index<r.index?-1:1:i.transactionId<r.transactionId?-1:1).findIndex(i=>i.transactionId===e.transactionId&&i.index===e.index);if(n===-1)throw new Error("Protocol config out ref not found in reference inputs");return BigInt(n)}function Y(e,o,t){let n=[];for(let i=0;i<e.length;i++){let r=e[i],s=o[i];if(s===0n)continue;let[a,g]=dt(r.tokenAAmount,r.tokenBAmount,r.datum,s,r.rewardAmount,t);n.push({poolIndex:i,deltaAmount:s,outputAmount:a,platformFee:g})}return n}var K=e=>{if(!e)return;let[o,t]=e.split("#");return new gt.TransactionInput({transactionId:ft.fromHex(o),index:BigInt(t)})};import{toHex as It}from"@evolution-sdk/evolution/Bytes32";var W=class{constructor(){}async calculateSwapOut(o,t){if(!o||!o.address)throw new Error("Please connect a wallet first.");let n=(await o.address()).networkId,i=X(Date.now(),n),r=await Promise.all(t.pools.map(c=>this.getUtxoOrThrow(o,c.poolOutRef,"Pool input"))),s=_(n),a=t.protocolConfigOutRef??s.protocolScriptOutRef,g=await this.getUtxoOrThrow(o,a,"Protocol config");if(!g.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let d=H(g.datumOption),p=await Promise.all(t.pools.map(async(c,w)=>{let h=r[w];if(!h.datumOption)throw new Error(`Pool input UTxO ${w} does not contain a datum.`);let m=v(h.datumOption),f=E(m.tokenX),P=E(m.tokenY),B=h.assets.lovelace,O=u=>u.unit===A?B:$(h.assets,u.policyId,u.assetName),T=null;c.stakingOutRef&&(T=await this.getUtxoOrThrow(o,c.stakingOutRef,"Staking"));let l=0n;return f.unit===A&&T&&i>m.lastWithdrawEpoch&&(l=await this.getRewardAmount(o,n,T)),{tokenAAmount:O(f),tokenBAmount:O(P),datum:m,rewardAmount:l}})),I=t.pools.map(c=>c.deltaAmount);return Y(p,I,d.platformFeeRate).map(c=>c.outputAmount)}async submitSwap(o,t){if(!o||!o.address)throw new Error("Please connect a wallet first.");let n=(await o.address()).networkId,i=X(Date.now(),n),r=await Promise.all(t.pools.map(l=>this.getUtxoOrThrow(o,l.poolOutRef,"Pool input"))),s=_(n),a=s.poolScriptOutRef,g=t.protocolConfigOutRef??s.protocolScriptOutRef,d=await this.getUtxoOrThrow(o,a,"Pool script"),p=await this.getUtxoOrThrow(o,g,"Protocol config");if(!p.datumOption)throw new Error("Protocol config UTxO does not contain a datum.");let I=H(p.datumOption),x=[],c=[];for(let l=0;l<t.pools.length;l++){let u=t.pools[l],b=r[l];if(!b.datumOption)throw new Error(`Pool input UTxO ${l} does not contain a datum.`);let y=v(b.datumOption),R=E(y.tokenX),C=E(y.tokenY),q=b.assets.lovelace,k=D=>D.unit===A?q:$(b.assets,D.policyId,D.assetName),F=null;u.stakingOutRef&&(F=await this.getUtxoOrThrow(o,u.stakingOutRef,"Staking")),c.push(F),x.push({tokenAAmount:k(R),tokenBAmount:k(C),datum:y,utxo:b,tokenA:R,tokenB:C})}let w=t.pools.map(l=>l.deltaAmount),h=Y(x,w,I.platformFeeRate);h.forEach((l,u)=>{let b=t.pools[u].minOutChangeAmount??0n;if(l.outputAmount<b)throw new Error(`Expected swap output at least ${b} but got ${l.outputAmount}`)});let m=o.newTx(),f=[p];f.push(d),c.forEach(l=>{l&&f.push(l)}),m=m.readFrom({referenceInputs:f});let P=J(p,f);m=m.withdraw({stakeCredential:M(d.scriptRef),amount:0n,redeemer:S(null,r,w,P)});for(let l=0;l<x.length;l++){let u=x[l],b=h.find(D=>D.poolIndex===l);if(!b)continue;let{deltaAmount:y,platformFee:R,outputAmount:C}=b,q=G({...u.datum,platformFeeX:BigInt(u.datum.platformFeeX)+(y>0?R:0n),platformFeeY:BigInt(u.datum.platformFeeY)+(y<0?R:0n),lastWithdrawEpoch:i,totalSwapFee:BigInt(u.datum.totalSwapFee)+I.swapFee}),k=this.buildDeltaAssets(y>0?u.tokenA:u.tokenB,y>0?u.tokenB:u.tokenA,y,C,I.swapFee),F=ot(u.utxo.assets,k);if(m=m.payToAddress({address:u.utxo.address,assets:F,datum:q}),m=m.collectFrom({inputs:[u.utxo],redeemer:S(u.utxo,r,w,P)}),u.tokenA.unit===A&&i>u.datum.lastWithdrawEpoch&&c[l]){let D=await this.getRewardAmount(o,n,c[l]);m=m.withdraw({stakeCredential:M(c[l].scriptRef),amount:D,redeemer:S(u.utxo,r,w,P)})}}m=m.attachMetadata({label:674n,metadata:new Map([["msg",["Danogo Multi-Pool Swap"]]])}),m.setValidity({from:BigInt(Date.now()-12e4),to:BigInt(Date.now()+24e4)});let T=await(await(await m.build({scriptDataFormat:"array"})).sign()).submit();return It(T.hash)}getPoolsFromOgmiosTx(o,t,n){let i=_(t),r=n??i.poolScriptHash;if(!r)throw new Error("Pool script hash is required but not provided or not found for this network.");let s=[];return o.outputs.forEach((a,g)=>{let d=a.value,p=d[r];if(p&&a.datum){for(let[I,x]of Object.entries(p))if(x===1n){let c=n+I,w=`${o.id}#${g}`,h=d.ada.lovelace,m=V(d),f=v(a.datum),P=f.tokenX,B=f.tokenY,O=T=>{if(T===A)return h;let l=T.slice(0,56),u=T.slice(56),y=m.find(R=>R.policyId===l)?.assets.find(R=>R.name===u);return y?y.value:0n};s.push({outRef:w,address:a.address,coin:h,multiAssets:m,validityNft:c,tokenA:P,tokenAReserve:O(P),tokenB:B,tokenBReserve:O(B),lpFeeRate:f.lpFeeRate,priceLowerNum:f.sqrtLowerPriceNum,priceLowerDen:f.sqrtLowerPriceDen,priceUpperNum:f.sqrtUpperPriceNum,priceUpperDen:f.sqrtUpperPriceDen,platformFeeA:f.platformFeeX,platformFeeB:f.platformFeeY,minAChange:f.minXChange,minBChange:f.minYChange,lpTokenTotalSupply:f.circulatingLPToken,lastWithdrawEpoch:f.lastWithdrawEpoch,totalSwapFee:f.totalSwapFee})}}}),s}async getUserTokenBalance(o,t){return(await o.getWalletUtxos()).reduce((i,r)=>i+(t.unit===A?r.assets.lovelace:$(r.assets,t.policyId,t.assetName)||0n),0n)}buildDeltaAssets(o,t,n,i,r){let s=n>0n?n:-n,a;if(o.unit===A?a=ht(s+r):a=tt(o.policyId,o.assetName,s,r),t.unit===A)a=At(a,i);else{let g=tt(t.policyId,t.assetName,-i);a=ot(a,g)}return a}async getRewardAmount(o,t,n){let i=new Z.RewardAccount({networkId:t,stakeCredential:M(n.scriptRef)}),r=Z.toBech32(i);return(await o.getDelegation(r)).rewards}async getUtxoOrThrow(o,t,n){let i=K(t);if(!i)throw new Error(`Invalid ${n} output reference: ${t}`);let r=await o.getUtxosByOutRef([i]);if(!r||r.length===0)throw new Error(`${n} ${t} UTxO not found or spent.`);return r[0]}},Qt=W;export{Qt as default};
|