@gardenfi/core 0.2.0-beta.34 → 0.2.0-beta.35
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/index.cjs +1 -1
- package/dist/index.js +3 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var li=Object.defineProperty;var hi=(e,t,r)=>t in e?li(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var nt=(e,t,r)=>hi(e,typeof t!="symbol"?t+"":t,r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=require("@catalogfi/utils"),J=require("@gardenfi/orderbook"),ge=require("@gardenfi/utils"),Ne=require("viem"),di=require("varuint-bitcoin"),pi=require("tiny-secp256k1"),Nr=require("@catalogfi/wallets"),gn=require("bitcoinjs-lib"),bi=require("bignumber.js");function Tr(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const a=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,a.get?a:{enumerable:!0,get:()=>e[r]})}}return t.default=e,Object.freeze(t)}const Ur=Tr(di),ft=Tr(pi),de=Tr(gn);var gr=(e=>(e[e.evm=14400]="evm",e[e.btc=288]="btc",e))(gr||{}),pe=(e=>(e.Idle="Idle",e.Initiate="Initiate",e.Redeem="Redeem",e.Refund="Refund",e))(pe||{});function qt(e){return{formatters:void 0,fees:void 0,serializers:void 0,...e}}const yi=qt({id:42161,name:"Arbitrum One",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:{default:{http:["https://arb1.arbitrum.io/rpc"]}},blockExplorers:{default:{name:"Arbiscan",url:"https://arbiscan.io",apiUrl:"https://api.arbiscan.io/api"}},contracts:{multicall3:{address:"0xca11bde05977b3631167028862be2a173976ca11",blockCreated:7654707}}}),_i=qt({id:421614,name:"Arbitrum Sepolia",nativeCurrency:{name:"Arbitrum Sepolia Ether",symbol:"ETH",decimals:18},rpcUrls:{default:{http:["https://sepolia-rollup.arbitrum.io/rpc"]}},blockExplorers:{default:{name:"Arbiscan",url:"https://sepolia.arbiscan.io",apiUrl:"https://api-sepolia.arbiscan.io/api"}},contracts:{multicall3:{address:"0xca11bde05977b3631167028862be2a173976ca11",blockCreated:81930}},testnet:!0}),gi=qt({id:1,name:"Ethereum",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:{default:{http:["https://cloudflare-eth.com"]}},blockExplorers:{default:{name:"Etherscan",url:"https://etherscan.io",apiUrl:"https://api.etherscan.io/api"}},contracts:{ensRegistry:{address:"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},ensUniversalResolver:{address:"0xce01f8eee7E479C928F8919abD53E553a36CeF67",blockCreated:19258213},multicall3:{address:"0xca11bde05977b3631167028862be2a173976ca11",blockCreated:14353601}}}),wi=qt({id:11155111,name:"Sepolia",nativeCurrency:{name:"Sepolia Ether",symbol:"ETH",decimals:18},rpcUrls:{default:{http:["https://rpc2.sepolia.org"]}},blockExplorers:{default:{name:"Etherscan",url:"https://sepolia.etherscan.io",apiUrl:"https://api-sepolia.etherscan.io/api"}},contracts:{multicall3:{address:"0xca11bde05977b3631167028862be2a173976ca11",blockCreated:751532},ensRegistry:{address:"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},ensUniversalResolver:{address:"0xc8Af999e38273D658BE1b921b88A9Ddf005769cC",blockCreated:5317080}},testnet:!0});function wr(e){return typeof e=="string"&&(e=Buffer.from(e,"hex")),e.length===32?e:e.subarray(1,33)}function it(e,t){if(!e)throw new Error(t)}function mi(e){return Buffer.concat([Uint8Array.from([192]),vi(e)])}function vi(e){const t=Ur.encodingLength(e.length),r=Buffer.allocUnsafe(t);return Ur.encode(e.length,r),Buffer.concat([r,e])}function xi(e,t){if(e.compare(t)>0){const r=e;e=t,t=r}return[e,t]}const yt=e=>e.length===64?e:e.slice(2),Ei=e=>{if(!e)return!1;try{const t=Buffer.from(e,"hex");return ft.isPoint(t)}catch{return!1}},Bi={ethereum:gi,ethereum_arbitrum:yi,ethereum_sepolia:wi,arbitrum_sepolia:_i,ethereum_localnet:J.EthereumLocalnet,arbitrum_localnet:J.ArbitrumLocalnet},Ri=async(e,t)=>{var a;const r=Bi[e];if(r)try{if(r.id===((a=t.chain)==null?void 0:a.id))return C.Ok({message:"Already on the network",walletClient:t});await t.switchChain({id:r.id});const o=Ne.createWalletClient({account:t.account,chain:r,transport:Ne.custom(window.ethereum)});return C.Ok({message:"Switched chain",walletClient:o})}catch(o){if(Si(o))try{await t.addChain({chain:r});const s=Ne.createWalletClient({account:t.account,chain:r,transport:Ne.custom(window.ethereum)});return C.Ok({message:"Added network",walletClient:s})}catch{return C.Err("Failed to add network")}else return C.Err("Failed to switch network")}else return C.Err("Chain not supported")},Si=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code===4902;var ae=(e=>(e.Created="Created",e.Matched="Matched",e.InitiateDetected="InitiateDetected",e.Initiated="Initiated",e.CounterPartyInitiateDetected="CounterPartyInitiateDetected",e.CounterPartyInitiated="CounterPartyInitiated",e.RedeemDetected="RedeemDetected",e.Redeemed="Redeemed",e.CounterPartyRedeemDetected="CounterPartyRedeemDetected",e.CounterPartyRedeemed="CounterPartyRedeemed",e.Completed="Completed",e.CounterPartySwapExpired="CounterPartySwapExpired",e.Expired="Expired",e.RefundDetected="RefundDetected",e.Refunded="Refunded",e.CounterPartyRefundDetected="CounterPartyRefundDetected",e.CounterPartyRefunded="CounterPartyRefunded",e.Cancelled="Cancelled",e))(ae||{}),ee=(e=>(e.Idle="Idle",e.InitiateDetected="InitiateDetected",e.Initiated="Initiated",e.RedeemDetected="RedeemDetected",e.Redeemed="Redeemed",e.RefundDetected="RefundDetected",e.Refunded="Refunded",e.Expired="Expired",e))(ee||{});const wn=(e,t,r)=>{const a=Ft(e.source_swap,t),o=Ft(e.destination_swap,r);if(a===ee.RedeemDetected)return ae.CounterPartyRedeemDetected;if(a===ee.Redeemed)return ae.CounterPartyRedeemed;if(o===ee.RedeemDetected)return ae.RedeemDetected;if(o===ee.Redeemed)return ae.Redeemed;if(o===ee.RefundDetected)return ae.CounterPartyRefundDetected;if(o===ee.Refunded)return ae.CounterPartyRefunded;if(a===ee.RefundDetected)return ae.RefundDetected;if(a===ee.Refunded)return ae.Refunded;if(o===ee.Expired)return ae.CounterPartySwapExpired;if(a===ee.Expired)return ae.Expired;const s=Number(e.create_order.additional_data.deadline)*1e3;return o===ee.InitiateDetected?ae.CounterPartyInitiateDetected:o===ee.Initiated?ae.CounterPartyInitiated:Dr(s,1)?ae.Expired:a===ee.InitiateDetected?ae.InitiateDetected:Dr(s,12)?ae.Expired:a===ee.Initiated?ae.Initiated:ae.Matched},Ft=(e,t)=>{if(e.redeem_tx_hash)return e.redeem_block_number?ee.Redeemed:ee.RedeemDetected;if(e.refund_tx_hash)return e.refund_block_number?ee.Refunded:ee.RefundDetected;if(Number(e.initiate_block_number)){const r=Number(e.initiate_block_number)+e.timelock;if(t>r)return ee.Expired}return e.initiate_tx_hash?e.initiate_block_number?ee.Initiated:ee.InitiateDetected:ee.Idle},mn=(e,t,r)=>{const a=wn(e,t,r);switch(console.log("orderId: ",e.create_order.create_id," orderStatus :",a),a){case ae.Matched:return pe.Initiate;case ae.CounterPartyInitiated:return pe.Redeem;case ae.Expired:return pe.Refund;default:return pe.Idle}},Dr=(e,t=0)=>{const r=Date.now(),a=e*1e3+t*36e5;return r>=a},Ai=[{inputs:[{internalType:"address",name:"token_",type:"address"},{internalType:"string",name:"name",type:"string"},{internalType:"string",name:"version",type:"string"}],stateMutability:"nonpayable",type:"constructor"},{inputs:[],name:"InvalidShortString",type:"error"},{inputs:[{internalType:"string",name:"str",type:"string"}],name:"StringTooLong",type:"error"},{anonymous:!1,inputs:[],name:"EIP712DomainChanged",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"bytes32",name:"orderID",type:"bytes32"},{indexed:!0,internalType:"bytes32",name:"secretHash",type:"bytes32"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"}],name:"Initiated",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"bytes32",name:"orderID",type:"bytes32"},{indexed:!0,internalType:"bytes32",name:"secretHash",type:"bytes32"},{indexed:!1,internalType:"bytes",name:"secret",type:"bytes"}],name:"Redeemed",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"bytes32",name:"orderID",type:"bytes32"}],name:"Refunded",type:"event"},{inputs:[],name:"eip712Domain",outputs:[{internalType:"bytes1",name:"fields",type:"bytes1"},{internalType:"string",name:"name",type:"string"},{internalType:"string",name:"version",type:"string"},{internalType:"uint256",name:"chainId",type:"uint256"},{internalType:"address",name:"verifyingContract",type:"address"},{internalType:"bytes32",name:"salt",type:"bytes32"},{internalType:"uint256[]",name:"extensions",type:"uint256[]"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"redeemer",type:"address"},{internalType:"uint256",name:"timelock",type:"uint256"},{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"bytes32",name:"secretHash",type:"bytes32"}],name:"initiate",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"redeemer",type:"address"},{internalType:"uint256",name:"timelock",type:"uint256"},{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"bytes32",name:"secretHash",type:"bytes32"},{internalType:"bytes",name:"signature",type:"bytes"}],name:"initiateWithSignature",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"bytes32",name:"orderID",type:"bytes32"},{internalType:"bytes",name:"signature",type:"bytes"}],name:"instantRefund",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{components:[{internalType:"address",name:"redeemer",type:"address"},{internalType:"uint256",name:"expiry",type:"uint256"},{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"bytes32",name:"secretHash",type:"bytes32"},{internalType:"bytes",name:"signature",type:"bytes"}],internalType:"struct HTLC.InitWithSig[]",name:"inits",type:"tuple[]"},{components:[{internalType:"bytes32",name:"orderID",type:"bytes32"},{internalType:"bytes",name:"secret",type:"bytes"}],internalType:"struct HTLC.Redeem[]",name:"redeems",type:"tuple[]"},{components:[{internalType:"bytes32",name:"orderID",type:"bytes32"}],internalType:"struct HTLC.Refund[]",name:"refunds",type:"tuple[]"}],name:"multicall",outputs:[{internalType:"bool[]",name:"results",type:"bool[]"}],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"bytes32",name:"",type:"bytes32"}],name:"orders",outputs:[{internalType:"bool",name:"isFulfilled",type:"bool"},{internalType:"address",name:"initiator",type:"address"},{internalType:"address",name:"redeemer",type:"address"},{internalType:"uint256",name:"initiatedAt",type:"uint256"},{internalType:"uint256",name:"timelock",type:"uint256"},{internalType:"uint256",name:"amount",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"bytes32",name:"orderID",type:"bytes32"},{internalType:"bytes",name:"secret",type:"bytes"}],name:"redeem",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"bytes32",name:"orderID",type:"bytes32"}],name:"refund",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"token",outputs:[{internalType:"contract IERC20",name:"",type:"address"}],stateMutability:"view",type:"function"}];class vn{constructor(t,r,a){this.url=new ge.Url("/relayer",r),this.auth=a,this.order=t}async init(t,r){if(!t.account)return C.Err("No account found");if(t.account.address.toLowerCase()!==this.order.source_swap.initiator.toLowerCase())return C.Err("Account address and order initiator mismatch");if(!r){const m=await ge.fetchEVMBlockNumber(t);if(m.error)return C.Err(m.error);r=m.val}if(Ft(this.order.source_swap,r)!==ee.Idle)return C.Err("Invalid swap status");const{create_order:o,source_swap:s}=this.order;if(!s.amount||!s.redeemer||!o.timelock||!o.secret_hash)return C.Err("Invalid order");const c=ge.with0x(o.secret_hash),u=BigInt(o.timelock),p=ge.with0x(s.redeemer),w=BigInt(s.amount);try{const m=await this.auth.getToken();if(m.error)return C.Err(m.error);const v=Ne.getContract({address:ge.with0x(this.order.source_swap.asset),abi:Ai,client:t}),T=await v.read.token(),O=await ge.checkAllowanceAndApprove(Number(w),T,this.order.source_swap.asset,t);if(O.error)return C.Err(O.error);const R=await v.read.eip712Domain(),k=await t.signTypedData({account:t.account,domain:{name:R[1],version:R[2],chainId:Number(R[3]),verifyingContract:R[4]},types:{Initiate:[{name:"redeemer",type:"address"},{name:"timelock",type:"uint256"},{name:"amount",type:"uint256"},{name:"secretHash",type:"bytes32"}]},primaryType:"Initiate",message:{redeemer:p,timelock:u,amount:w,secretHash:c}}),A=await C.Fetcher.post(this.url.endpoint("initiate"),{body:JSON.stringify({order_id:o.create_id,signature:k,perform_on:"Source"}),headers:{Authorization:ge.Authorization(m.val),"Content-Type":"application/json"}});return A.error?C.Err(A.error):A.result?C.Ok(A.result):C.Err("Init: No result found")}catch(m){return console.log("init error :",m),C.Err(String(m))}}async redeem(t,r){try{const a=await this.auth.getToken();if(a.error)return C.Err(a.error);const o=await C.Fetcher.post(this.url.endpoint("redeem"),{body:JSON.stringify({order_id:t,secret:C.trim0x(r),perform_on:"Destination"}),headers:{Authorization:ge.Authorization(a.val),"Content-Type":"application/json"}});return o.error?C.Err(o.error):o.result?C.Ok(o.result):C.Err("Redeem: No result found")}catch(a){return C.Err(String(a))}}}const Ti=Buffer.from("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","hex"),Ii=Buffer.from("483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8","hex"),ki=Buffer.concat([Ti,Ii]),Ci=Buffer.from("0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0","hex"),$r={failedToCreateInternalPubkey:"failed to create internal pubkey",failedToTweakPubkey:"failed to tweak pubkey"};function Oi(){const e=gn.crypto.sha256(Buffer.from("GardenHTLC","utf-8")),t=ft.pointMultiply(Buffer.concat([Buffer.from("04","hex"),ki]),e);if(!t)throw new Error($r.failedToCreateInternalPubkey);const r=ft.pointAdd(Ci,t);if(!r)throw new Error($r.failedToCreateInternalPubkey);return wr(Buffer.from(r))}const ye={secretMismatch:"invalid secret",secretHashLenMismatch:"secret hash should be 32 bytes",pubkeyLenMismatch:"pubkey should be 32 bytes",zeroOrNegativeExpiry:"expiry should be greater than 0",htlcAddressGenerationFailed:"failed to generate htlc address",notFunded:"address not funded",noCounterpartySigs:"counterparty signatures are required",counterPartySigNotFound:e=>"counterparty signature not found for utxo "+e,invalidCounterpartySigForUTXO:e=>"invalid counterparty signature for utxo "+e,htlcNotExpired:e=>`HTLC not expired, need more ${e} blocks`,controlBlockGenerationFailed:"failed to generate control block",invalidLeaf:"invalid leaf"},Ot=192;de.initEccLib(ft);class Nt{constructor(t,r,a,o,s,c,u,p){this.secretHash=a,this.redeemerPubkey=o,this.initiatorPubkey=s,this.expiry=c,this.signer=t,this.network=u,this.internalPubkey=Oi(),this.initiateAmount=r,this.utxoHashes=p}static async from(t,r,a,o,s,c,u){a=a.startsWith("0x")?a.slice(2):a,it(a.length===64,ye.secretHashLenMismatch),it(o.length===64||o.length===66,`initiator ${ye.pubkeyLenMismatch}`),it(s.length===64||s.length===66,`redeemer ${ye.pubkeyLenMismatch}`),it(c>0,ye.zeroOrNegativeExpiry);const p=await t.getNetwork();return new Nt(t,r,a,wr(s).toString("hex"),wr(o).toString("hex"),c,p,u)}address(){const{address:t}=de.payments.p2tr({internalPubkey:this.internalPubkey,network:this.network,scriptTree:this.leaves()});if(!t)throw new Error(ye.htlcAddressGenerationFailed);return t}id(){return this.address()}async _buildRawTx(t,r){const a=new de.Transaction;a.version=2;const o=this.address(),s=await this.signer.getProvider();let c=[];if(this.utxoHashes&&this.utxoHashes.length>0)for(const p of this.utxoHashes){const w=await s.getTransaction(p);for(let m=0;m<w.vout.length;m++){const v=w.vout[m];v.scriptpubkey_address===o&&c.push({txid:w.txid,vout:m,value:v.value,status:{confirmed:!1}})}}else c=await s.getUTXOs(o);const u=c.reduce((p,w)=>p+w.value,0);if(u===0)throw new Error(`${o} ${ye.notFunded}`);for(let p=0;p<c.length;p++)a.addInput(Buffer.from(c[p].txid,"hex").reverse(),c[p].vout);return r??(r=await s.suggestFee(o,u,Nr.Urgency.MEDIUM)),a.addOutput(de.address.toOutputScript(t,this.network),u-r),{tx:a,usedUtxos:c}}async buildRawTx(t){return await this._buildRawTx(await this.signer.getAddress(),t)}getOutputScript(){return de.address.toOutputScript(this.address(),this.network)}async init(t){return t??(t=await(await this.signer.getProvider()).suggestFee(await this.signer.getAddress(),this.initiateAmount,Nr.Urgency.MEDIUM)),await this.signer.send(this.address(),this.initiateAmount,t)}async instantRefund(t,r){it(t.length>0,ye.noCounterpartySigs);const{tx:a,usedUtxos:o}=await this.buildRawTx(r);for(const v of o)if(!t.find(T=>T.utxo===v.txid))throw new Error(ye.counterPartySigNotFound(v.txid));const s=this.getOutputScript(),c=de.Transaction.SIGHASH_DEFAULT,u=this.leafHash(2),p=o.map(v=>v.value),w=rr(s,o.length);for(let v=0;v<a.ins.length;v++){const T=a.hashForWitnessV1(v,w,p,c,u);if(!ft.verifySchnorr(T,Buffer.from(this.redeemerPubkey,"hex"),Buffer.from(t[v].sig,"hex")))throw new Error(ye.invalidCounterpartySigForUTXO(t[v].utxo));const O=await this.signer.signSchnorr(T),R=Buffer.from(a.ins[v].hash).reverse().toString("hex"),k=t.find(A=>A.utxo===R);if(!k)throw new Error(ye.counterPartySigNotFound(R));a.setWitness(v,[Buffer.from(k.sig,"hex"),O,this.instantRefundLeaf(),this.generateControlBlockFor(2)])}return await(await this.signer.getProvider()).broadcast(a.toHex())}async redeem(t,r,a){it(de.crypto.sha256(Buffer.from(t,"hex")).toString("hex")===this.secretHash,ye.secretMismatch);const{tx:o,usedUtxos:s}=await this._buildRawTx(r??await this.signer.getAddress(),a),c=this.leafHash(1),u=s.map(v=>v.value),p=rr(this.getOutputScript(),s.length),w=de.Transaction.SIGHASH_DEFAULT;for(let v=0;v<o.ins.length;v++){const T=o.hashForWitnessV1(v,p,u,w,c),O=await this.signer.signSchnorr(T);o.setWitness(v,[O,Buffer.from(t,"hex"),this.redeemLeaf(),this.generateControlBlockFor(1)])}return await(await this.signer.getProvider()).broadcast(o.toHex())}async refund(t,r){const{tx:a,usedUtxos:o}=await this._buildRawTx(t??await this.signer.getAddress(),r),[s,c]=await this.canRefund(o);if(!s)throw new Error(ye.htlcNotExpired(c));const u=this.leafHash(0),p=o.map(T=>T.value),w=rr(this.getOutputScript(),o.length),m=de.Transaction.SIGHASH_DEFAULT;for(let T=0;T<a.ins.length;T++){a.ins[T].sequence=this.expiry;const O=a.hashForWitnessV1(T,w,p,m,u),R=await this.signer.signSchnorr(O);a.setWitness(T,[R,this.refundLeaf(),this.generateControlBlockFor(0)])}return await(await this.signer.getProvider()).broadcast(a.toHex())}async canRefund(t){const a=await(await this.signer.getProvider()).getLatestTip();for(const o of t){let s=0;if(o.status.confirmed&&o.status.block_height+this.expiry>a?s=o.status.block_height+this.expiry-a+1:o.status.confirmed||(s=this.expiry+1),s>0)return[!1,s]}return[!0,0]}generateControlBlockFor(t){let r;switch(t){case 1:r=this.redeemLeaf();break;case 0:r=this.refundLeaf();break;case 2:r=this.instantRefundLeaf();break;default:throw new Error(ye.invalidLeaf)}const a=de.payments.p2tr({internalPubkey:this.internalPubkey,network:this.network,scriptTree:this.leaves(),redeem:{output:r,redeemVersion:Ot}});if(!a.witness)throw new Error(ye.controlBlockGenerationFailed);return a.witness[a.witness.length-1]}leafHash(t){let r=this.redeemLeaf();return t===0&&(r=this.refundLeaf()),t===2&&(r=this.instantRefundLeaf()),de.crypto.taggedHash("TapLeaf",mi(r))}refundLeaf(){return de.script.fromASM(`
|
|
1
|
+
"use strict";var li=Object.defineProperty;var hi=(e,t,r)=>t in e?li(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var nt=(e,t,r)=>hi(e,typeof t!="symbol"?t+"":t,r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=require("@catalogfi/utils"),J=require("@gardenfi/orderbook"),ge=require("@gardenfi/utils"),Ne=require("viem"),di=require("varuint-bitcoin"),pi=require("tiny-secp256k1"),Nr=require("@catalogfi/wallets"),gn=require("bitcoinjs-lib"),bi=require("bignumber.js");function Tr(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const a=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,a.get?a:{enumerable:!0,get:()=>e[r]})}}return t.default=e,Object.freeze(t)}const Ur=Tr(di),ft=Tr(pi),de=Tr(gn);var gr=(e=>(e[e.evm=14400]="evm",e[e.btc=288]="btc",e))(gr||{}),pe=(e=>(e.Idle="Idle",e.Initiate="Initiate",e.Redeem="Redeem",e.Refund="Refund",e))(pe||{});function qt(e){return{formatters:void 0,fees:void 0,serializers:void 0,...e}}const yi=qt({id:42161,name:"Arbitrum One",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:{default:{http:["https://arb1.arbitrum.io/rpc"]}},blockExplorers:{default:{name:"Arbiscan",url:"https://arbiscan.io",apiUrl:"https://api.arbiscan.io/api"}},contracts:{multicall3:{address:"0xca11bde05977b3631167028862be2a173976ca11",blockCreated:7654707}}}),_i=qt({id:421614,name:"Arbitrum Sepolia",nativeCurrency:{name:"Arbitrum Sepolia Ether",symbol:"ETH",decimals:18},rpcUrls:{default:{http:["https://sepolia-rollup.arbitrum.io/rpc"]}},blockExplorers:{default:{name:"Arbiscan",url:"https://sepolia.arbiscan.io",apiUrl:"https://api-sepolia.arbiscan.io/api"}},contracts:{multicall3:{address:"0xca11bde05977b3631167028862be2a173976ca11",blockCreated:81930}},testnet:!0}),gi=qt({id:1,name:"Ethereum",nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18},rpcUrls:{default:{http:["https://cloudflare-eth.com"]}},blockExplorers:{default:{name:"Etherscan",url:"https://etherscan.io",apiUrl:"https://api.etherscan.io/api"}},contracts:{ensRegistry:{address:"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},ensUniversalResolver:{address:"0xce01f8eee7E479C928F8919abD53E553a36CeF67",blockCreated:19258213},multicall3:{address:"0xca11bde05977b3631167028862be2a173976ca11",blockCreated:14353601}}}),wi=qt({id:11155111,name:"Sepolia",nativeCurrency:{name:"Sepolia Ether",symbol:"ETH",decimals:18},rpcUrls:{default:{http:["https://rpc2.sepolia.org"]}},blockExplorers:{default:{name:"Etherscan",url:"https://sepolia.etherscan.io",apiUrl:"https://api-sepolia.etherscan.io/api"}},contracts:{multicall3:{address:"0xca11bde05977b3631167028862be2a173976ca11",blockCreated:751532},ensRegistry:{address:"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},ensUniversalResolver:{address:"0xc8Af999e38273D658BE1b921b88A9Ddf005769cC",blockCreated:5317080}},testnet:!0});function wr(e){return typeof e=="string"&&(e=Buffer.from(e,"hex")),e.length===32?e:e.subarray(1,33)}function it(e,t){if(!e)throw new Error(t)}function mi(e){return Buffer.concat([Uint8Array.from([192]),vi(e)])}function vi(e){const t=Ur.encodingLength(e.length),r=Buffer.allocUnsafe(t);return Ur.encode(e.length,r),Buffer.concat([r,e])}function xi(e,t){if(e.compare(t)>0){const r=e;e=t,t=r}return[e,t]}const yt=e=>e.length===64?e:e.slice(2),Ei=e=>{if(!e)return!1;try{const t=Buffer.from(e,"hex");return ft.isPoint(t)}catch{return!1}},Bi={ethereum:gi,ethereum_arbitrum:yi,ethereum_sepolia:wi,arbitrum_sepolia:_i,ethereum_localnet:J.EthereumLocalnet,arbitrum_localnet:J.ArbitrumLocalnet},Ri=async(e,t)=>{var a;const r=Bi[e];if(r)try{if(r.id===((a=t.chain)==null?void 0:a.id))return C.Ok({message:"Already on the network",walletClient:t});await t.switchChain({id:r.id});const o=Ne.createWalletClient({account:t.account,chain:r,transport:Ne.custom(window.ethereum)});return C.Ok({message:"Switched chain",walletClient:o})}catch(o){if(Si(o))try{await t.addChain({chain:r});const s=Ne.createWalletClient({account:t.account,chain:r,transport:Ne.custom(window.ethereum)});return C.Ok({message:"Added network",walletClient:s})}catch{return C.Err("Failed to add network")}else return C.Err("Failed to switch network")}else return C.Err("Chain not supported")},Si=e=>typeof e=="object"&&e!==null&&"code"in e&&e.code===4902;var ae=(e=>(e.Created="Created",e.Matched="Matched",e.InitiateDetected="InitiateDetected",e.Initiated="Initiated",e.CounterPartyInitiateDetected="CounterPartyInitiateDetected",e.CounterPartyInitiated="CounterPartyInitiated",e.RedeemDetected="RedeemDetected",e.Redeemed="Redeemed",e.CounterPartyRedeemDetected="CounterPartyRedeemDetected",e.CounterPartyRedeemed="CounterPartyRedeemed",e.Completed="Completed",e.CounterPartySwapExpired="CounterPartySwapExpired",e.Expired="Expired",e.RefundDetected="RefundDetected",e.Refunded="Refunded",e.CounterPartyRefundDetected="CounterPartyRefundDetected",e.CounterPartyRefunded="CounterPartyRefunded",e.Cancelled="Cancelled",e))(ae||{}),ee=(e=>(e.Idle="Idle",e.InitiateDetected="InitiateDetected",e.Initiated="Initiated",e.RedeemDetected="RedeemDetected",e.Redeemed="Redeemed",e.RefundDetected="RefundDetected",e.Refunded="Refunded",e.Expired="Expired",e))(ee||{});const wn=(e,t,r)=>{const a=Ft(e.source_swap,t),o=Ft(e.destination_swap,r);if(a===ee.RedeemDetected)return ae.CounterPartyRedeemDetected;if(a===ee.Redeemed)return ae.CounterPartyRedeemed;if(o===ee.RedeemDetected)return ae.RedeemDetected;if(o===ee.Redeemed)return ae.Redeemed;if(o===ee.RefundDetected)return ae.CounterPartyRefundDetected;if(o===ee.Refunded)return ae.CounterPartyRefunded;if(a===ee.RefundDetected)return ae.RefundDetected;if(a===ee.Refunded)return ae.Refunded;if(o===ee.Expired)return ae.CounterPartySwapExpired;if(a===ee.Expired)return ae.Expired;const s=Number(e.create_order.additional_data.deadline);return o===ee.InitiateDetected?ae.CounterPartyInitiateDetected:o===ee.Initiated?ae.CounterPartyInitiated:Dr(s,1)?ae.Expired:a===ee.InitiateDetected?ae.InitiateDetected:Dr(s,12)?ae.Expired:a===ee.Initiated?ae.Initiated:ae.Matched},Ft=(e,t)=>{if(e.redeem_tx_hash)return e.redeem_block_number?ee.Redeemed:ee.RedeemDetected;if(e.refund_tx_hash)return e.refund_block_number?ee.Refunded:ee.RefundDetected;if(Number(e.initiate_block_number)){const r=Number(e.initiate_block_number)+e.timelock;if(t>r)return ee.Expired}return e.initiate_tx_hash?e.initiate_block_number?ee.Initiated:ee.InitiateDetected:ee.Idle},mn=(e,t,r)=>{const a=wn(e,t,r);switch(console.log("orderId: ",e.create_order.create_id," orderStatus :",a),a){case ae.Matched:return pe.Initiate;case ae.CounterPartyInitiated:return pe.Redeem;case ae.Expired:return pe.Refund;default:return pe.Idle}},Dr=(e,t=0)=>{const r=Date.now(),a=e*1e3+t*36e5;return r>=a},Ai=[{inputs:[{internalType:"address",name:"token_",type:"address"},{internalType:"string",name:"name",type:"string"},{internalType:"string",name:"version",type:"string"}],stateMutability:"nonpayable",type:"constructor"},{inputs:[],name:"InvalidShortString",type:"error"},{inputs:[{internalType:"string",name:"str",type:"string"}],name:"StringTooLong",type:"error"},{anonymous:!1,inputs:[],name:"EIP712DomainChanged",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"bytes32",name:"orderID",type:"bytes32"},{indexed:!0,internalType:"bytes32",name:"secretHash",type:"bytes32"},{indexed:!1,internalType:"uint256",name:"amount",type:"uint256"}],name:"Initiated",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"bytes32",name:"orderID",type:"bytes32"},{indexed:!0,internalType:"bytes32",name:"secretHash",type:"bytes32"},{indexed:!1,internalType:"bytes",name:"secret",type:"bytes"}],name:"Redeemed",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"bytes32",name:"orderID",type:"bytes32"}],name:"Refunded",type:"event"},{inputs:[],name:"eip712Domain",outputs:[{internalType:"bytes1",name:"fields",type:"bytes1"},{internalType:"string",name:"name",type:"string"},{internalType:"string",name:"version",type:"string"},{internalType:"uint256",name:"chainId",type:"uint256"},{internalType:"address",name:"verifyingContract",type:"address"},{internalType:"bytes32",name:"salt",type:"bytes32"},{internalType:"uint256[]",name:"extensions",type:"uint256[]"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"redeemer",type:"address"},{internalType:"uint256",name:"timelock",type:"uint256"},{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"bytes32",name:"secretHash",type:"bytes32"}],name:"initiate",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"redeemer",type:"address"},{internalType:"uint256",name:"timelock",type:"uint256"},{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"bytes32",name:"secretHash",type:"bytes32"},{internalType:"bytes",name:"signature",type:"bytes"}],name:"initiateWithSignature",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"bytes32",name:"orderID",type:"bytes32"},{internalType:"bytes",name:"signature",type:"bytes"}],name:"instantRefund",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{components:[{internalType:"address",name:"redeemer",type:"address"},{internalType:"uint256",name:"expiry",type:"uint256"},{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"bytes32",name:"secretHash",type:"bytes32"},{internalType:"bytes",name:"signature",type:"bytes"}],internalType:"struct HTLC.InitWithSig[]",name:"inits",type:"tuple[]"},{components:[{internalType:"bytes32",name:"orderID",type:"bytes32"},{internalType:"bytes",name:"secret",type:"bytes"}],internalType:"struct HTLC.Redeem[]",name:"redeems",type:"tuple[]"},{components:[{internalType:"bytes32",name:"orderID",type:"bytes32"}],internalType:"struct HTLC.Refund[]",name:"refunds",type:"tuple[]"}],name:"multicall",outputs:[{internalType:"bool[]",name:"results",type:"bool[]"}],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"bytes32",name:"",type:"bytes32"}],name:"orders",outputs:[{internalType:"bool",name:"isFulfilled",type:"bool"},{internalType:"address",name:"initiator",type:"address"},{internalType:"address",name:"redeemer",type:"address"},{internalType:"uint256",name:"initiatedAt",type:"uint256"},{internalType:"uint256",name:"timelock",type:"uint256"},{internalType:"uint256",name:"amount",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"bytes32",name:"orderID",type:"bytes32"},{internalType:"bytes",name:"secret",type:"bytes"}],name:"redeem",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"bytes32",name:"orderID",type:"bytes32"}],name:"refund",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[],name:"token",outputs:[{internalType:"contract IERC20",name:"",type:"address"}],stateMutability:"view",type:"function"}];class vn{constructor(t,r,a){this.url=new ge.Url("/relayer",r),this.auth=a,this.order=t}async init(t,r){if(!t.account)return C.Err("No account found");if(t.account.address.toLowerCase()!==this.order.source_swap.initiator.toLowerCase())return C.Err("Account address and order initiator mismatch");if(!r){const m=await ge.fetchEVMBlockNumber(t);if(m.error)return C.Err(m.error);r=m.val}if(Ft(this.order.source_swap,r)!==ee.Idle)return C.Err("Invalid swap status");const{create_order:o,source_swap:s}=this.order;if(!s.amount||!s.redeemer||!o.timelock||!o.secret_hash)return C.Err("Invalid order");const c=ge.with0x(o.secret_hash),u=BigInt(o.timelock),p=ge.with0x(s.redeemer),w=BigInt(s.amount);try{const m=await this.auth.getToken();if(m.error)return C.Err(m.error);const v=Ne.getContract({address:ge.with0x(this.order.source_swap.asset),abi:Ai,client:t}),T=await v.read.token(),O=await ge.checkAllowanceAndApprove(Number(w),T,this.order.source_swap.asset,t);if(O.error)return C.Err(O.error);const R=await v.read.eip712Domain(),k=await t.signTypedData({account:t.account,domain:{name:R[1],version:R[2],chainId:Number(R[3]),verifyingContract:R[4]},types:{Initiate:[{name:"redeemer",type:"address"},{name:"timelock",type:"uint256"},{name:"amount",type:"uint256"},{name:"secretHash",type:"bytes32"}]},primaryType:"Initiate",message:{redeemer:p,timelock:u,amount:w,secretHash:c}}),A=await C.Fetcher.post(this.url.endpoint("initiate"),{body:JSON.stringify({order_id:o.create_id,signature:k,perform_on:"Source"}),headers:{Authorization:ge.Authorization(m.val),"Content-Type":"application/json"}});return A.error?C.Err(A.error):A.result?C.Ok(A.result):C.Err("Init: No result found")}catch(m){return console.log("init error :",m),C.Err(String(m))}}async redeem(t,r){try{const a=await this.auth.getToken();if(a.error)return C.Err(a.error);const o=await C.Fetcher.post(this.url.endpoint("redeem"),{body:JSON.stringify({order_id:t,secret:C.trim0x(r),perform_on:"Destination"}),headers:{Authorization:ge.Authorization(a.val),"Content-Type":"application/json"}});return o.error?C.Err(o.error):o.result?C.Ok(o.result):C.Err("Redeem: No result found")}catch(a){return C.Err(String(a))}}}const Ti=Buffer.from("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798","hex"),Ii=Buffer.from("483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8","hex"),ki=Buffer.concat([Ti,Ii]),Ci=Buffer.from("0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0","hex"),$r={failedToCreateInternalPubkey:"failed to create internal pubkey",failedToTweakPubkey:"failed to tweak pubkey"};function Oi(){const e=gn.crypto.sha256(Buffer.from("GardenHTLC","utf-8")),t=ft.pointMultiply(Buffer.concat([Buffer.from("04","hex"),ki]),e);if(!t)throw new Error($r.failedToCreateInternalPubkey);const r=ft.pointAdd(Ci,t);if(!r)throw new Error($r.failedToCreateInternalPubkey);return wr(Buffer.from(r))}const ye={secretMismatch:"invalid secret",secretHashLenMismatch:"secret hash should be 32 bytes",pubkeyLenMismatch:"pubkey should be 32 bytes",zeroOrNegativeExpiry:"expiry should be greater than 0",htlcAddressGenerationFailed:"failed to generate htlc address",notFunded:"address not funded",noCounterpartySigs:"counterparty signatures are required",counterPartySigNotFound:e=>"counterparty signature not found for utxo "+e,invalidCounterpartySigForUTXO:e=>"invalid counterparty signature for utxo "+e,htlcNotExpired:e=>`HTLC not expired, need more ${e} blocks`,controlBlockGenerationFailed:"failed to generate control block",invalidLeaf:"invalid leaf"},Ot=192;de.initEccLib(ft);class Nt{constructor(t,r,a,o,s,c,u,p){this.secretHash=a,this.redeemerPubkey=o,this.initiatorPubkey=s,this.expiry=c,this.signer=t,this.network=u,this.internalPubkey=Oi(),this.initiateAmount=r,this.utxoHashes=p}static async from(t,r,a,o,s,c,u){a=a.startsWith("0x")?a.slice(2):a,it(a.length===64,ye.secretHashLenMismatch),it(o.length===64||o.length===66,`initiator ${ye.pubkeyLenMismatch}`),it(s.length===64||s.length===66,`redeemer ${ye.pubkeyLenMismatch}`),it(c>0,ye.zeroOrNegativeExpiry);const p=await t.getNetwork();return new Nt(t,r,a,wr(s).toString("hex"),wr(o).toString("hex"),c,p,u)}address(){const{address:t}=de.payments.p2tr({internalPubkey:this.internalPubkey,network:this.network,scriptTree:this.leaves()});if(!t)throw new Error(ye.htlcAddressGenerationFailed);return t}id(){return this.address()}async _buildRawTx(t,r){const a=new de.Transaction;a.version=2;const o=this.address(),s=await this.signer.getProvider();let c=[];if(this.utxoHashes&&this.utxoHashes.length>0)for(const p of this.utxoHashes){const w=await s.getTransaction(p);for(let m=0;m<w.vout.length;m++){const v=w.vout[m];v.scriptpubkey_address===o&&c.push({txid:w.txid,vout:m,value:v.value,status:{confirmed:!1}})}}else c=await s.getUTXOs(o);const u=c.reduce((p,w)=>p+w.value,0);if(u===0)throw new Error(`${o} ${ye.notFunded}`);for(let p=0;p<c.length;p++)a.addInput(Buffer.from(c[p].txid,"hex").reverse(),c[p].vout);return r??(r=await s.suggestFee(o,u,Nr.Urgency.MEDIUM)),a.addOutput(de.address.toOutputScript(t,this.network),u-r),{tx:a,usedUtxos:c}}async buildRawTx(t){return await this._buildRawTx(await this.signer.getAddress(),t)}getOutputScript(){return de.address.toOutputScript(this.address(),this.network)}async init(t){return t??(t=await(await this.signer.getProvider()).suggestFee(await this.signer.getAddress(),this.initiateAmount,Nr.Urgency.MEDIUM)),await this.signer.send(this.address(),this.initiateAmount,t)}async instantRefund(t,r){it(t.length>0,ye.noCounterpartySigs);const{tx:a,usedUtxos:o}=await this.buildRawTx(r);for(const v of o)if(!t.find(T=>T.utxo===v.txid))throw new Error(ye.counterPartySigNotFound(v.txid));const s=this.getOutputScript(),c=de.Transaction.SIGHASH_DEFAULT,u=this.leafHash(2),p=o.map(v=>v.value),w=rr(s,o.length);for(let v=0;v<a.ins.length;v++){const T=a.hashForWitnessV1(v,w,p,c,u);if(!ft.verifySchnorr(T,Buffer.from(this.redeemerPubkey,"hex"),Buffer.from(t[v].sig,"hex")))throw new Error(ye.invalidCounterpartySigForUTXO(t[v].utxo));const O=await this.signer.signSchnorr(T),R=Buffer.from(a.ins[v].hash).reverse().toString("hex"),k=t.find(A=>A.utxo===R);if(!k)throw new Error(ye.counterPartySigNotFound(R));a.setWitness(v,[Buffer.from(k.sig,"hex"),O,this.instantRefundLeaf(),this.generateControlBlockFor(2)])}return await(await this.signer.getProvider()).broadcast(a.toHex())}async redeem(t,r,a){it(de.crypto.sha256(Buffer.from(t,"hex")).toString("hex")===this.secretHash,ye.secretMismatch);const{tx:o,usedUtxos:s}=await this._buildRawTx(r??await this.signer.getAddress(),a),c=this.leafHash(1),u=s.map(v=>v.value),p=rr(this.getOutputScript(),s.length),w=de.Transaction.SIGHASH_DEFAULT;for(let v=0;v<o.ins.length;v++){const T=o.hashForWitnessV1(v,p,u,w,c),O=await this.signer.signSchnorr(T);o.setWitness(v,[O,Buffer.from(t,"hex"),this.redeemLeaf(),this.generateControlBlockFor(1)])}return await(await this.signer.getProvider()).broadcast(o.toHex())}async refund(t,r){const{tx:a,usedUtxos:o}=await this._buildRawTx(t??await this.signer.getAddress(),r),[s,c]=await this.canRefund(o);if(!s)throw new Error(ye.htlcNotExpired(c));const u=this.leafHash(0),p=o.map(T=>T.value),w=rr(this.getOutputScript(),o.length),m=de.Transaction.SIGHASH_DEFAULT;for(let T=0;T<a.ins.length;T++){a.ins[T].sequence=this.expiry;const O=a.hashForWitnessV1(T,w,p,m,u),R=await this.signer.signSchnorr(O);a.setWitness(T,[R,this.refundLeaf(),this.generateControlBlockFor(0)])}return await(await this.signer.getProvider()).broadcast(a.toHex())}async canRefund(t){const a=await(await this.signer.getProvider()).getLatestTip();for(const o of t){let s=0;if(o.status.confirmed&&o.status.block_height+this.expiry>a?s=o.status.block_height+this.expiry-a+1:o.status.confirmed||(s=this.expiry+1),s>0)return[!1,s]}return[!0,0]}generateControlBlockFor(t){let r;switch(t){case 1:r=this.redeemLeaf();break;case 0:r=this.refundLeaf();break;case 2:r=this.instantRefundLeaf();break;default:throw new Error(ye.invalidLeaf)}const a=de.payments.p2tr({internalPubkey:this.internalPubkey,network:this.network,scriptTree:this.leaves(),redeem:{output:r,redeemVersion:Ot}});if(!a.witness)throw new Error(ye.controlBlockGenerationFailed);return a.witness[a.witness.length-1]}leafHash(t){let r=this.redeemLeaf();return t===0&&(r=this.refundLeaf()),t===2&&(r=this.instantRefundLeaf()),de.crypto.taggedHash("TapLeaf",mi(r))}refundLeaf(){return de.script.fromASM(`
|
|
2
2
|
${de.script.number.encode(this.expiry).toString("hex")}
|
|
3
3
|
OP_CHECKSEQUENCEVERIFY
|
|
4
4
|
OP_DROP
|
package/dist/index.js
CHANGED
|
@@ -230,7 +230,9 @@ const Ui = (e, t, r) => {
|
|
|
230
230
|
if (o === Z.Expired)
|
|
231
231
|
return ie.CounterPartySwapExpired;
|
|
232
232
|
if (a === Z.Expired) return ie.Expired;
|
|
233
|
-
const s = Number(
|
|
233
|
+
const s = Number(
|
|
234
|
+
e.create_order.additional_data.deadline
|
|
235
|
+
);
|
|
234
236
|
return o === Z.InitiateDetected ? ie.CounterPartyInitiateDetected : o === Z.Initiated ? ie.CounterPartyInitiated : Yr(s, 1) ? ie.Expired : a === Z.InitiateDetected ? ie.InitiateDetected : Yr(s, 12) ? ie.Expired : a === Z.Initiated ? ie.Initiated : ie.Matched;
|
|
235
237
|
}, Br = (e, t) => {
|
|
236
238
|
if (e.redeem_tx_hash)
|