@gardenfi/core 0.3.0-beta.7 → 0.3.0-beta.9

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 CHANGED
@@ -20,7 +20,7 @@
20
20
  OP_CHECKSIGADD
21
21
  OP_2
22
22
  OP_NUMEQUAL
23
- `.trim().replace(/\s+/g," "))}leaves(){return[{version:sr,output:this.redeemLeaf()},[{version:sr,output:this.refundLeaf()},{version:sr,output:this.instantRefundLeaf()}]]}generateMerkleProofFor(t){const r=this.leafHash(1),n=this.leafHash(2),i=this.leafHash(0);switch(t){case 1:{const a=Na(i,n);return[oe.crypto.taggedHash("TapBranch",Buffer.concat(a))]}case 0:return[n,r];case 2:return[i,r];default:throw new Error(me.invalidLeaf)}}}function or(e,t){const r=[];for(let n=0;n<t;n++)r.push(e);return r}class Ja{constructor(){this.cache={}}set(t,r,n,i){const a={txHash:n,timeStamp:Date.now(),btcRedeemUTXO:i};this.cache[`${r}_${t.create_order.create_id}`]=a}get(t,r){return this.cache[`${r}_${t.create_order.create_id}`]||null}remove(t,r){delete this.cache[`${r}_${t.create_order.create_id}`]}}class Xa{constructor(t){if(this.eventListeners=new Map,this.getOrderThreshold=20,this.useRelay=!0,this.orderBook=new X.Orderbook({url:t.orderbookURl,walletClient:t.wallets.evmWallet,auth:t.auth}),this.quote=t.quote,this.secretManager=t.secretManager,this.wallets=t.wallets,this.orderbookUrl=t.orderbookURl,this.auth=t.auth,this.orderExecutorCache=new Ja,!t.wallets.evmWallet.account)throw new Error("Account not found in evmWallet");this.evmAddress=t.wallets.evmWallet.account.address,this.blockNumberFetcher=t.blockNumberFetcher}setUseRelay(t){this.useRelay=t}async swap(t){const r=await this.validateAndFillParams(t);if(r.error)return k.Err(r.error);const{sendAddress:n,receiveAddress:i,timelock:a}=r.val;let f=t.nonce;if(!f){const P=await this.orderBook.getOrdersCount(this.evmAddress);if(P.error)return k.Err(P.error);f=P.val+1}const u=this.secretManager.generateSecret(f);if(u.error)return k.Err(u.error);const{strategyId:l,btcAddress:b}=t.additionalData,g={strategy_id:l,...b&&{bitcoin_optional_recipient:b}},m={source_chain:t.fromAsset.chain,destination_chain:t.toAsset.chain,source_asset:t.fromAsset.atomicSwapAddress,destination_asset:t.toAsset.atomicSwapAddress,initiator_source_address:n,initiator_destination_address:i,source_amount:t.sendAmount,destination_amount:t.receiveAmount,fee:"1",nonce:f.toString(),timelock:a,secret_hash:k.trim0x(u.val.secretHash),min_destination_confirmations:t.minDestinationConfirmations??0,additional_data:g},v=await this.quote.getAttestedQuote(m);if(v.error)return k.Err(v.error);const A=await this.orderBook.createOrder(v.val);if(A.error)return k.Err(A.error);const B=await this.pollOrder(A.val);return B.error?k.Err(B.error):k.Ok(B.val)}async validateAndFillParams(t){if(t.fromAsset.chain===t.toAsset.chain&&t.fromAsset.atomicSwapAddress===t.toAsset.atomicSwapAddress)return k.Err("Source and destination assets cannot be the same");if(X.isMainnet(t.fromAsset.chain)&&!X.isMainnet(t.toAsset.chain)||!X.isMainnet(t.fromAsset.chain)&&X.isMainnet(t.toAsset.chain))return k.Err("Both assets should be on the same network (either mainnet or testnet)");if(X.isBitcoin(t.fromAsset.chain)||X.isBitcoin(t.toAsset.chain)){if(!this.wallets.btcWallet)return k.Err("btcWallet is required for bitcoin chain. Please provide btcWallet in the constructor");if(!t.additionalData.btcAddress)return k.Err("btcAddress in additionalData is required for bitcoin chain")}const r=await this.getAddresses(t.fromAsset.chain);if(r.error)return k.Err(r.error);const n=await this.getAddresses(t.toAsset.chain);if(n.error)return k.Err(n.error);const i=this.validateAmount(t.sendAmount);if(i.error)return k.Err(i.error);const a=this.validateAmount(t.receiveAmount);if(a.error)return k.Err(a.error);if(i<a)return k.Err("Send amount should be greater than receive amount");const f=X.getTimeLock(t.fromAsset.chain);return f?k.Ok({sendAddress:r.val,receiveAddress:n.val,timelock:t.timelock??f}):k.Err("Unsupported chain for timelock")}async getAddresses(t){var n;switch(X.getBlockchainType(t)){case X.BlockchainType.EVM:return this.wallets.evmWallet.account?k.Ok(this.wallets.evmWallet.account.address):k.Err("EVM Wallet not found");case X.BlockchainType.Bitcoin:{const i=await((n=this.wallets.btcWallet)==null?void 0:n.getPublicKey());return!i||!Ma(i)?k.Err("Invalid btc public key"):k.Ok(st(i))}default:return k.Err("Unsupported chain")}}validateAmount(t){if(t==null||t.includes("."))return k.Err("Invalid amount ",t);const r=new Gs(t);return!r.isInteger()||r.isNaN()||r.lt(0)||r.isLessThanOrEqualTo(0)?k.Err("Invalid amount ",t):k.Ok(r)}async pollOrder(t){let r=await this.orderBook.getOrder(t,!0),n=0;for(;n<this.getOrderThreshold;){if(await we.sleep(1e3),n++,r.error){if(!r.error.includes("result is undefined"))return k.Err(r.error)}else if(r.val&&r.val.create_order.create_id.toLowerCase()===t.toLowerCase())return k.Ok(r.val);r=await this.orderBook.getOrder(t,!0)}return k.Err(`Order not found, createOrder id: ${t}`)}async execute(t=5e3){return await this.orderBook.subscribeToOrders(!0,t,async r=>{const n=Vi(r.data),i=await this.assignOrderStatus(n);this.emit("onPendingOrdersChanged",i);for(let a=0;a<i.length;a++){const f=i[a],u=xn(f.status);if(this.emit("log",f.create_order.create_id,`status: ${f.status}`),X.isBitcoin(f.source_swap.chain)&&f.status===Q.InitiateDetected){const l=this.getWallet(f.source_swap.chain);if(l.error){this.emit("error",f,l.error);continue}const b=await Wt.from(l.val,Number(f.source_swap.amount),f.create_order.secret_hash,st(f.source_swap.initiator),st(f.source_swap.redeemer),f.source_swap.timelock),g=f.create_order.additional_data.bitcoin_optional_recipient;if(g)try{const m=await b.generateInstantRefundSACP(g),v=this.orderbookUrl+"/orders/add-instant-refund-sacp";await k.Fetcher.post(v,{body:JSON.stringify({order_id:f.create_order.create_id,instant_refund_tx_bytes:m})})}catch(m){this.emit("error",f,"Failed to generate SACP: "+m)}}switch(u){case ce.Redeem:{const l=this.secretManager.generateSecret(Number(f.create_order.nonce));if(l.error){this.emit("error",f,l.error);return}switch(X.getBlockchainType(f.destination_swap.chain)){case X.BlockchainType.EVM:{await this.evmRedeem(f,l.val.secret);break}case X.BlockchainType.Bitcoin:{const b=this.getWallet(f.destination_swap.chain);if(b.error){this.emit("error",f,b.error);return}await this.btcRedeem(b.val,f,l.val.secret);break}default:this.emit("error",f,"Unsupported chain: "+f.destination_swap.chain)}break}case ce.Refund:{switch(X.getBlockchainType(f.source_swap.chain)){case X.BlockchainType.EVM:{this.emit("error",f,"EVM refund is automatically done by relay service");break}case X.BlockchainType.Bitcoin:{const l=this.getWallet(f.source_swap.chain);if(l.error){this.emit("error",f,l.error);return}await this.btcRefund(l.val,f);break}default:this.emit("error",f,"Unsupported chain: "+f.source_swap.chain)}break}}}},{per_page:500},!0)}async evmRedeem(t,r){if(this.emit("log",t.create_order.create_id,"executing evm redeem"),this.orderExecutorCache.get(t,ce.Redeem)){this.emit("log",t.create_order.create_id,"already redeemed");return}const a=await new Ki(t,this.orderbookUrl,this.auth).redeem(t.create_order.create_id,r);if(a.error){this.emit("error",t,a.error),a.error.includes("Order already redeemed")&&this.orderExecutorCache.set(t,ce.Redeem,t.destination_swap.redeem_tx_hash);return}this.orderExecutorCache.set(t,ce.Redeem,a.val),this.emit("success",t,ce.Redeem,a.val)}async btcRedeem(t,r,n){var u,l;const i=this.orderExecutorCache.get(r,ce.Redeem),a=(u=r.destination_swap.initiate_tx_hash.split(",").at(-1))==null?void 0:u.split(":").at(0);if(!a){this.emit("error",r,"Failed to get initiate_tx_hash");return}let f=!1;if(i)if(i.btcRedeemUTXO&&i.btcRedeemUTXO!==a)f=!0,this.emit("log",r.create_order.create_id,"rbf btc redeem");else{this.emit("log",r.create_order.create_id,"btcRedeem: already redeemed");return}else if(r.destination_swap.redeem_tx_hash&&!Number(r.destination_swap.redeem_block_number))try{const b=await(await t.getProvider()).getTransaction(r.destination_swap.redeem_tx_hash);let g=!1;for(const m of b.vin)if(m.txid===a){g=!0;break}if(g){this.orderExecutorCache.set(r,ce.Redeem,r.destination_swap.redeem_tx_hash,a),this.emit("log",r.create_order.create_id,"already a valid redeem");return}f=!0}catch(b){if(b.message.includes("Transaction not found"))f=!0;else{this.emit("error",r,"Failed to get redeem tx: "+b);return}}this.emit("log",r.create_order.create_id,"executing btc redeem");try{const g=await(await Wt.from(t,Number(r.destination_swap.amount),r.create_order.secret_hash,st(r.destination_swap.initiator),st(r.destination_swap.redeemer),r.destination_swap.timelock,f?[a]:[])).redeem(k.trim0x(n),(l=r.create_order.additional_data)==null?void 0:l.bitcoin_optional_recipient);f?this.emit("log",r.create_order.create_id,"rbf: btc redeem success"):this.emit("success",r,ce.Redeem,g),this.orderExecutorCache.set(r,ce.Redeem,g,a)}catch(b){this.emit("error",r,"Failed btc redeem: "+b)}}async btcRefund(t,r){var n;if(!this.orderExecutorCache.get(r,ce.Refund)){this.emit("log",r.create_order.create_id,"executing btc refund");try{const a=await(await Wt.from(t,Number(r.source_swap.amount),r.create_order.secret_hash,st(r.source_swap.initiator),st(r.source_swap.redeemer),r.source_swap.timelock)).refund((n=r.create_order.additional_data)==null?void 0:n.bitcoin_optional_recipient);this.orderExecutorCache.set(r,ce.Refund,a),this.emit("success",r,ce.Refund,a)}catch(i){this.emit("error",r,"Failed btc refund: "+i)}}}getWallet(t){switch(X.getBlockchainType(t)){case X.BlockchainType.EVM:return k.Ok(this.wallets.evmWallet);case X.BlockchainType.Bitcoin:return k.Ok(this.wallets.btcWallet);default:return k.Err("Unsupported chain for wallet")}}emit(t,...r){(this.eventListeners.get(t)??[]).forEach(i=>{i(...r)})}on(t,r){const n=this.eventListeners.get(t)??[];n.push(r),this.eventListeners.set(t,n)}off(t,r){const n=this.eventListeners.get(t)??[],i=n.indexOf(r);i!==-1&&n.splice(i,1)}async fetchCurrentBlockNumbers(t,r){if(!r||!r.source||!r.destination)return k.Err("Provide wallets to fetch the current block number");const n=X.isBitcoin(t.source_swap.chain)?await we.fetchBitcoinBlockNumber(await r.source.getProvider()):await we.fetchEVMBlockNumber(r.source);if(n.error)return k.Err(n.error);const i=X.isBitcoin(t.destination_swap.chain)?await we.fetchBitcoinBlockNumber(await r.destination.getProvider()):await we.fetchEVMBlockNumber(r.destination);return i.error?k.Err(i.error):k.Ok({source:n.val,destination:i.val})}async assignOrderStatus(t){var i;const r=await((i=this.blockNumberFetcher)==null?void 0:i.fetchBlockNumbers()),n=[];for(let a=0;a<t.length;a++){const f=t[a],u=f.source_swap.chain,l=f.destination_swap.chain,b=this.getWallet(u),g=this.getWallet(l);if(b.error||g.error||!b.val||!g.val){this.emit("error",f,"Source or Destination Wallet not found while executing order");continue}let m=r==null?void 0:r.val[u],v=r==null?void 0:r.val[l];if(!m||!v){const B=await this.fetchCurrentBlockNumbers(f,{source:b.val,destination:g.val});if(B.error){this.emit("error",f,"Error while fetching CurrentBlockNumbers: "+B.error);continue}m=B.val.source,v=B.val.destination}const A=wn(f,m,v);n.push({...f,status:A})}return n}}class Qa{constructor(t,r){this.url=new we.Url("/blocknumber/"+r,t)}async fetchBlockNumbers(){try{const t=await k.Fetcher.get(this.url);return k.Ok(t)}catch(t){return k.Err("Failed to fetch block numbers",t)}}}var Qe=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Za(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function ef(e){if(e.__esModule)return e;var t=e.default;if(typeof t=="function"){var r=function n(){return this instanceof n?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};r.prototype=t.prototype}else r={};return Object.defineProperty(r,"__esModule",{value:!0}),Object.keys(e).forEach(function(n){var i=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(r,n,i.get?i:{enumerable:!0,get:function(){return e[n]}})}),r}var Yi={},St={},At={};Object.defineProperty(At,"__esModule",{value:!0});At.testnet=At.bitcoin=void 0;At.bitcoin={messagePrefix:`Bitcoin Signed Message:
23
+ `.trim().replace(/\s+/g," "))}leaves(){return[{version:sr,output:this.redeemLeaf()},[{version:sr,output:this.refundLeaf()},{version:sr,output:this.instantRefundLeaf()}]]}generateMerkleProofFor(t){const r=this.leafHash(1),n=this.leafHash(2),i=this.leafHash(0);switch(t){case 1:{const a=Na(i,n);return[oe.crypto.taggedHash("TapBranch",Buffer.concat(a))]}case 0:return[n,r];case 2:return[i,r];default:throw new Error(me.invalidLeaf)}}}function or(e,t){const r=[];for(let n=0;n<t;n++)r.push(e);return r}class Ja{constructor(){this.cache={}}set(t,r,n,i){const a={txHash:n,timeStamp:Date.now(),btcRedeemUTXO:i};this.cache[`${r}_${t.create_order.create_id}`]=a}get(t,r){return this.cache[`${r}_${t.create_order.create_id}`]||null}remove(t,r){delete this.cache[`${r}_${t.create_order.create_id}`]}}class Xa{constructor(t){if(this.eventListeners=new Map,this.getOrderThreshold=20,this.useRelay=!0,this.refundSacpCache=new Map,this.orderBook=new X.Orderbook({url:t.orderbookURl,walletClient:t.wallets.evmWallet,auth:t.auth}),this.quote=t.quote,this.secretManager=t.secretManager,this.wallets=t.wallets,this.orderbookUrl=t.orderbookURl,this.auth=t.auth,this.orderExecutorCache=new Ja,!t.wallets.evmWallet.account)throw new Error("Account not found in evmWallet");this.evmAddress=t.wallets.evmWallet.account.address,this.blockNumberFetcher=t.blockNumberFetcher}setUseRelay(t){this.useRelay=t}async swap(t){const r=await this.validateAndFillParams(t);if(r.error)return k.Err(r.error);const{sendAddress:n,receiveAddress:i,timelock:a}=r.val;let f=t.nonce;if(!f){const P=await this.orderBook.getOrdersCount(this.evmAddress);if(P.error)return k.Err(P.error);f=P.val+1}const u=this.secretManager.generateSecret(f);if(u.error)return k.Err(u.error);const{strategyId:l,btcAddress:b}=t.additionalData,g={strategy_id:l,...b&&{bitcoin_optional_recipient:b}},m={source_chain:t.fromAsset.chain,destination_chain:t.toAsset.chain,source_asset:t.fromAsset.atomicSwapAddress,destination_asset:t.toAsset.atomicSwapAddress,initiator_source_address:n,initiator_destination_address:i,source_amount:t.sendAmount,destination_amount:t.receiveAmount,fee:"1",nonce:f.toString(),timelock:a,secret_hash:k.trim0x(u.val.secretHash),min_destination_confirmations:t.minDestinationConfirmations??0,additional_data:g},v=await this.quote.getAttestedQuote(m);if(v.error)return k.Err(v.error);const A=await this.orderBook.createOrder(v.val);if(A.error)return k.Err(A.error);const B=await this.pollOrder(A.val);return B.error?k.Err(B.error):k.Ok(B.val)}async validateAndFillParams(t){if(t.fromAsset.chain===t.toAsset.chain&&t.fromAsset.atomicSwapAddress===t.toAsset.atomicSwapAddress)return k.Err("Source and destination assets cannot be the same");if(X.isMainnet(t.fromAsset.chain)&&!X.isMainnet(t.toAsset.chain)||!X.isMainnet(t.fromAsset.chain)&&X.isMainnet(t.toAsset.chain))return k.Err("Both assets should be on the same network (either mainnet or testnet)");if(X.isBitcoin(t.fromAsset.chain)||X.isBitcoin(t.toAsset.chain)){if(!this.wallets.btcWallet)return k.Err("btcWallet is required for bitcoin chain. Please provide btcWallet in the constructor");if(!t.additionalData.btcAddress)return k.Err("btcAddress in additionalData is required for bitcoin chain")}const r=await this.getAddresses(t.fromAsset.chain);if(r.error)return k.Err(r.error);const n=await this.getAddresses(t.toAsset.chain);if(n.error)return k.Err(n.error);const i=this.validateAmount(t.sendAmount);if(i.error)return k.Err(i.error);const a=this.validateAmount(t.receiveAmount);if(a.error)return k.Err(a.error);if(i<a)return k.Err("Send amount should be greater than receive amount");const f=X.getTimeLock(t.fromAsset.chain);return f?k.Ok({sendAddress:r.val,receiveAddress:n.val,timelock:t.timelock??f}):k.Err("Unsupported chain for timelock")}async getAddresses(t){var n;switch(X.getBlockchainType(t)){case X.BlockchainType.EVM:return this.wallets.evmWallet.account?k.Ok(this.wallets.evmWallet.account.address):k.Err("EVM Wallet not found");case X.BlockchainType.Bitcoin:{const i=await((n=this.wallets.btcWallet)==null?void 0:n.getPublicKey());return!i||!Ma(i)?k.Err("Invalid btc public key"):k.Ok(st(i))}default:return k.Err("Unsupported chain")}}validateAmount(t){if(t==null||t.includes("."))return k.Err("Invalid amount ",t);const r=new Gs(t);return!r.isInteger()||r.isNaN()||r.lt(0)||r.isLessThanOrEqualTo(0)?k.Err("Invalid amount ",t):k.Ok(r)}async pollOrder(t){let r=await this.orderBook.getOrder(t,!0),n=0;for(;n<this.getOrderThreshold;){if(await we.sleep(1e3),n++,r.error){if(!r.error.includes("result is undefined"))return k.Err(r.error)}else if(r.val&&r.val.create_order.create_id.toLowerCase()===t.toLowerCase())return k.Ok(r.val);r=await this.orderBook.getOrder(t,!0)}return k.Err(`Order not found, createOrder id: ${t}`)}async execute(t=5e3){return await this.orderBook.subscribeToOrders(!0,t,async r=>{const n=Vi(r.data),i=await this.assignOrderStatus(n);this.emit("onPendingOrdersChanged",i);for(let a=0;a<i.length;a++){const f=i[a],u=xn(f.status);if(X.isBitcoin(f.source_swap.chain)&&f.status===Q.InitiateDetected){const l=this.getWallet(f.source_swap.chain);if(l.error){this.emit("error",f,l.error);continue}await this.postRefundSACP(f,l.val)}switch(u){case ce.Redeem:{const l=this.secretManager.generateSecret(Number(f.create_order.nonce));if(l.error){this.emit("error",f,l.error);return}switch(X.getBlockchainType(f.destination_swap.chain)){case X.BlockchainType.EVM:{await this.evmRedeem(f,l.val.secret);break}case X.BlockchainType.Bitcoin:{const b=this.getWallet(f.destination_swap.chain);if(b.error){this.emit("error",f,b.error);return}await this.btcRedeem(b.val,f,l.val.secret);break}default:this.emit("error",f,"Unsupported chain: "+f.destination_swap.chain)}break}case ce.Refund:{switch(X.getBlockchainType(f.source_swap.chain)){case X.BlockchainType.EVM:{this.emit("error",f,"EVM refund is automatically done by relay service");break}case X.BlockchainType.Bitcoin:{const l=this.getWallet(f.source_swap.chain);if(l.error){this.emit("error",f,l.error);return}await this.btcRefund(l.val,f);break}default:this.emit("error",f,"Unsupported chain: "+f.source_swap.chain)}break}}}},{per_page:500},!0)}async evmRedeem(t,r){if(this.emit("log",t.create_order.create_id,"executing evm redeem"),this.orderExecutorCache.get(t,ce.Redeem)){this.emit("log",t.create_order.create_id,"already redeemed");return}const a=await new Ki(t,this.orderbookUrl,this.auth).redeem(t.create_order.create_id,r);if(a.error){this.emit("error",t,a.error),a.error.includes("Order already redeemed")&&this.orderExecutorCache.set(t,ce.Redeem,t.destination_swap.redeem_tx_hash);return}this.orderExecutorCache.set(t,ce.Redeem,a.val),this.emit("success",t,ce.Redeem,a.val)}async btcRedeem(t,r,n){var u,l;const i=this.orderExecutorCache.get(r,ce.Redeem),a=(u=r.destination_swap.initiate_tx_hash.split(",").at(-1))==null?void 0:u.split(":").at(0);if(!a){this.emit("error",r,"Failed to get initiate_tx_hash");return}let f=!1;if(i)if(i.btcRedeemUTXO&&i.btcRedeemUTXO!==a)f=!0,this.emit("log",r.create_order.create_id,"rbf btc redeem");else{this.emit("log",r.create_order.create_id,"btcRedeem: already redeemed");return}else if(r.destination_swap.redeem_tx_hash&&!Number(r.destination_swap.redeem_block_number))try{const b=await(await t.getProvider()).getTransaction(r.destination_swap.redeem_tx_hash);let g=!1;for(const m of b.vin)if(m.txid===a){g=!0;break}if(g){this.orderExecutorCache.set(r,ce.Redeem,r.destination_swap.redeem_tx_hash,a),this.emit("log",r.create_order.create_id,"already a valid redeem");return}f=!0}catch(b){if(b.message.includes("Transaction not found"))f=!0;else{this.emit("error",r,"Failed to get redeem tx: "+b);return}}this.emit("log",r.create_order.create_id,"executing btc redeem");try{const g=await(await Wt.from(t,Number(r.destination_swap.amount),r.create_order.secret_hash,st(r.destination_swap.initiator),st(r.destination_swap.redeemer),r.destination_swap.timelock,f?[a]:[])).redeem(k.trim0x(n),(l=r.create_order.additional_data)==null?void 0:l.bitcoin_optional_recipient);f?this.emit("log",r.create_order.create_id,"rbf: btc redeem success"):this.emit("success",r,ce.Redeem,g),this.orderExecutorCache.set(r,ce.Redeem,g,a)}catch(b){this.emit("error",r,"Failed btc redeem: "+b)}}async btcRefund(t,r){var n;if(!this.orderExecutorCache.get(r,ce.Refund)){this.emit("log",r.create_order.create_id,"executing btc refund");try{const a=await(await Wt.from(t,Number(r.source_swap.amount),r.create_order.secret_hash,st(r.source_swap.initiator),st(r.source_swap.redeemer),r.source_swap.timelock)).refund((n=r.create_order.additional_data)==null?void 0:n.bitcoin_optional_recipient);this.orderExecutorCache.set(r,ce.Refund,a),this.emit("success",r,ce.Refund,a)}catch(i){this.emit("error",r,"Failed btc refund: "+i)}}}getWallet(t){switch(X.getBlockchainType(t)){case X.BlockchainType.EVM:return k.Ok(this.wallets.evmWallet);case X.BlockchainType.Bitcoin:return k.Ok(this.wallets.btcWallet);default:return k.Err("Unsupported chain for wallet")}}async postRefundSACP(t,r){const n=this.refundSacpCache.get(t.create_order.create_id);if((n==null?void 0:n.initTxHash)===t.source_swap.initiate_tx_hash)return;const i=await Wt.from(r,Number(t.source_swap.amount),t.create_order.secret_hash,st(t.source_swap.initiator),st(t.source_swap.redeemer),t.source_swap.timelock),a=t.create_order.additional_data.bitcoin_optional_recipient;if(a)try{const f=await i.generateInstantRefundSACP(a),u=this.orderbookUrl+"/orders/add-instant-refund-sacp";(await k.Fetcher.post(u,{headers:{"Content-Type":"application/json"},body:JSON.stringify({order_id:t.create_order.create_id,instant_refund_tx_bytes:f})})).status==="Ok"&&this.refundSacpCache.set(t.create_order.create_id,{initTxHash:t.source_swap.initiate_tx_hash})}catch(f){this.emit("error",t,"Failed to generate and post SACP: "+f);return}}emit(t,...r){(this.eventListeners.get(t)??[]).forEach(i=>{i(...r)})}on(t,r){const n=this.eventListeners.get(t)??[];n.push(r),this.eventListeners.set(t,n)}off(t,r){const n=this.eventListeners.get(t)??[],i=n.indexOf(r);i!==-1&&n.splice(i,1)}async fetchCurrentBlockNumbers(t,r){if(!r||!r.source||!r.destination)return k.Err("Provide wallets to fetch the current block number");const n=X.isBitcoin(t.source_swap.chain)?await we.fetchBitcoinBlockNumber(await r.source.getProvider()):await we.fetchEVMBlockNumber(r.source);if(n.error)return k.Err(n.error);const i=X.isBitcoin(t.destination_swap.chain)?await we.fetchBitcoinBlockNumber(await r.destination.getProvider()):await we.fetchEVMBlockNumber(r.destination);return i.error?k.Err(i.error):k.Ok({source:n.val,destination:i.val})}async assignOrderStatus(t){var i;const r=await((i=this.blockNumberFetcher)==null?void 0:i.fetchBlockNumbers()),n=[];for(let a=0;a<t.length;a++){const f=t[a],u=f.source_swap.chain,l=f.destination_swap.chain,b=this.getWallet(u),g=this.getWallet(l);if(b.error||g.error||!b.val||!g.val){this.emit("error",f,"Source or Destination Wallet not found while executing order");continue}let m=r==null?void 0:r.val[u],v=r==null?void 0:r.val[l];if(!m||!v){const B=await this.fetchCurrentBlockNumbers(f,{source:b.val,destination:g.val});if(B.error){this.emit("error",f,"Error while fetching CurrentBlockNumbers: "+B.error);continue}m=B.val.source,v=B.val.destination}const A=wn(f,m,v);n.push({...f,status:A})}return n}}class Qa{constructor(t,r){this.url=new we.Url("/blocknumber/"+r,t)}async fetchBlockNumbers(){try{const t=await k.Fetcher.get(this.url);return k.Ok(t)}catch(t){return k.Err("Failed to fetch block numbers",t)}}}var Qe=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function Za(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function ef(e){if(e.__esModule)return e;var t=e.default;if(typeof t=="function"){var r=function n(){return this instanceof n?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};r.prototype=t.prototype}else r={};return Object.defineProperty(r,"__esModule",{value:!0}),Object.keys(e).forEach(function(n){var i=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(r,n,i.get?i:{enumerable:!0,get:function(){return e[n]}})}),r}var Yi={},St={},At={};Object.defineProperty(At,"__esModule",{value:!0});At.testnet=At.bitcoin=void 0;At.bitcoin={messagePrefix:`Bitcoin Signed Message:
24
24
  `,bech32:"bc",bip32:{public:76067358,private:76066276},pubKeyHash:0,scriptHash:5,wif:128};At.testnet={messagePrefix:`Bitcoin Signed Message:
25
25
  `,bech32:"tb",bip32:{public:70617039,private:70615956},pubKeyHash:111,scriptHash:196,wif:239};var Ji={},Vt={Array:function(e){return e!=null&&e.constructor===Array},Boolean:function(e){return typeof e=="boolean"},Function:function(e){return typeof e=="function"},Nil:function(e){return e==null},Number:function(e){return typeof e=="number"},Object:function(e){return typeof e=="object"},String:function(e){return typeof e=="string"},"":function(){return!0}};Vt.Null=Vt.Nil;for(var Gn in Vt)Vt[Gn].toJSON=(function(e){return e}).bind(null,Gn);var vn=Vt,ot=vn;function Xi(e){return e.name||e.toString().match(/function (.*?)\s*\(/)[1]}function En(e){return ot.Nil(e)?"":Xi(e.constructor)}function tf(e){return ot.Function(e)?"":ot.String(e)?JSON.stringify(e):e&&ot.Object(e)?"":e}function Bn(e,t){Error.captureStackTrace&&Error.captureStackTrace(e,t)}function pr(e){return ot.Function(e)?e.toJSON?e.toJSON():Xi(e):ot.Array(e)?"Array":e&&ot.Object(e)?"Object":e!==void 0?e:""}function Qi(e,t,r){var n=tf(t);return"Expected "+pr(e)+", got"+(r!==""?" "+r:"")+(n!==""?" "+n:"")}function ze(e,t,r){r=r||En(t),this.message=Qi(e,t,r),Bn(this,ze),this.__type=e,this.__value=t,this.__valueTypeName=r}ze.prototype=Object.create(Error.prototype);ze.prototype.constructor=ze;function rf(e,t,r,n,i){var a='" of type ';return t==="key"&&(a='" with key type '),Qi('property "'+pr(r)+a+pr(e),n,i)}function vt(e,t,r,n,i){e?(i=i||En(n),this.message=rf(e,r,t,n,i)):this.message='Unexpected property "'+t+'"',Bn(this,ze),this.__label=r,this.__property=t,this.__type=e,this.__value=n,this.__valueTypeName=i}vt.prototype=Object.create(Error.prototype);vt.prototype.constructor=ze;function nf(e,t){return new ze(e,{},t)}function sf(e,t,r){return e instanceof vt?(t=t+"."+e.__property,e=new vt(e.__type,t,e.__label,e.__value,e.__valueTypeName)):e instanceof ze&&(e=new vt(e.__type,t,r,e.__value,e.__valueTypeName)),Bn(e),e}var Zi={TfTypeError:ze,TfPropertyTypeError:vt,tfCustomError:nf,tfSubError:sf,tfJSON:pr,getValueTypeName:En},Mr,jn;function of(){if(jn)return Mr;jn=1;var e=vn,t=Zi;function r(S){return Buffer.isBuffer(S)}function n(S){return typeof S=="string"&&/^([0-9a-f]{2})+$/i.test(S)}function i(S,z){var M=S.toJSON();function $(ae){if(!S(ae))return!1;if(ae.length===z)return!0;throw t.tfCustomError(M+"(Length: "+z+")",M+"(Length: "+ae.length+")")}return $.toJSON=function(){return M},$}var a=i.bind(null,e.Array),f=i.bind(null,r),u=i.bind(null,n),l=i.bind(null,e.String);function b(S,z,M){M=M||e.Number;function $(ae,ke){return M(ae,ke)&&ae>S&&ae<z}return $.toJSON=function(){return`${M.toJSON()} between [${S}, ${z}]`},$}var g=Math.pow(2,53)-1;function m(S){return typeof S=="number"&&isFinite(S)}function v(S){return S<<24>>24===S}function A(S){return S<<16>>16===S}function B(S){return(S|0)===S}function P(S){return typeof S=="number"&&S>=-g&&S<=g&&Math.floor(S)===S}function T(S){return(S&255)===S}function C(S){return(S&65535)===S}function F(S){return S>>>0===S}function O(S){return typeof S=="number"&&S>=0&&S<=g&&Math.floor(S)===S}var L={ArrayN:a,Buffer:r,BufferN:f,Finite:m,Hex:n,HexN:u,Int8:v,Int16:A,Int32:B,Int53:P,Range:b,StringN:l,UInt8:T,UInt16:C,UInt32:F,UInt53:O};for(var U in L)L[U].toJSON=(function(S){return S}).bind(null,U);return Mr=L,Mr}var Qt=Zi,he=vn,De=Qt.tfJSON,es=Qt.TfTypeError,ts=Qt.TfPropertyTypeError,Mt=Qt.tfSubError,af=Qt.getValueTypeName,$e={arrayOf:function(t,r){t=Fe(t),r=r||{};function n(i,a){return!he.Array(i)||he.Nil(i)||r.minLength!==void 0&&i.length<r.minLength||r.maxLength!==void 0&&i.length>r.maxLength||r.length!==void 0&&i.length!==r.length?!1:i.every(function(f,u){try{return xe(t,f,a)}catch(l){throw Mt(l,u)}})}return n.toJSON=function(){var i="["+De(t)+"]";return r.length!==void 0?i+="{"+r.length+"}":(r.minLength!==void 0||r.maxLength!==void 0)&&(i+="{"+(r.minLength===void 0?0:r.minLength)+","+(r.maxLength===void 0?1/0:r.maxLength)+"}"),i},n},maybe:function e(t){t=Fe(t);function r(n,i){return he.Nil(n)||t(n,i,e)}return r.toJSON=function(){return"?"+De(t)},r},map:function(t,r){t=Fe(t),r&&(r=Fe(r));function n(i,a){if(!he.Object(i)||he.Nil(i))return!1;for(var f in i){try{r&&xe(r,f,a)}catch(l){throw Mt(l,f,"key")}try{var u=i[f];xe(t,u,a)}catch(l){throw Mt(l,f)}}return!0}return r?n.toJSON=function(){return"{"+De(r)+": "+De(t)+"}"}:n.toJSON=function(){return"{"+De(t)+"}"},n},object:function(t){var r={};for(var n in t)r[n]=Fe(t[n]);function i(a,f){if(!he.Object(a)||he.Nil(a))return!1;var u;try{for(u in r){var l=r[u],b=a[u];xe(l,b,f)}}catch(g){throw Mt(g,u)}if(f){for(u in a)if(!r[u])throw new ts(void 0,u)}return!0}return i.toJSON=function(){return De(r)},i},anyOf:function(){var t=[].slice.call(arguments).map(Fe);function r(n,i){return t.some(function(a){try{return xe(a,n,i)}catch{return!1}})}return r.toJSON=function(){return t.map(De).join("|")},r},allOf:function(){var t=[].slice.call(arguments).map(Fe);function r(n,i){return t.every(function(a){try{return xe(a,n,i)}catch{return!1}})}return r.toJSON=function(){return t.map(De).join(" & ")},r},quacksLike:function(t){function r(n){return t===af(n)}return r.toJSON=function(){return t},r},tuple:function(){var t=[].slice.call(arguments).map(Fe);function r(n,i){return he.Nil(n)||he.Nil(n.length)||i&&n.length!==t.length?!1:t.every(function(a,f){try{return xe(a,n[f],i)}catch(u){throw Mt(u,f)}})}return r.toJSON=function(){return"("+t.map(De).join(", ")+")"},r},value:function(t){function r(n){return n===t}return r.toJSON=function(){return t},r}};$e.oneOf=$e.anyOf;function Fe(e){if(he.String(e))return e[0]==="?"?$e.maybe(e.slice(1)):he[e]||$e.quacksLike(e);if(e&&he.Object(e)){if(he.Array(e)){if(e.length!==1)throw new TypeError("Expected compile() parameter of type Array of length 1");return $e.arrayOf(e[0])}return $e.object(e)}else if(he.Function(e))return e;return $e.value(e)}function xe(e,t,r,n){if(he.Function(e)){if(e(t,r))return!0;throw new es(n||e,t)}return xe(Fe(e),t,r)}for(var Xe in he)xe[Xe]=he[Xe];for(Xe in $e)xe[Xe]=$e[Xe];var Wn=of();for(Xe in Wn)xe[Xe]=Wn[Xe];xe.compile=Fe;xe.TfTypeError=es;xe.TfPropertyTypeError=ts;var ff=xe;(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.maybe=e.Boolean=e.Array=e.Buffer256bit=e.Network=e.typeforce=void 0,e.typeforce=ff,e.Network=e.typeforce.compile({messagePrefix:e.typeforce.oneOf(e.typeforce.Buffer,e.typeforce.String),bip32:{public:e.typeforce.UInt32,private:e.typeforce.UInt32},pubKeyHash:e.typeforce.UInt8,scriptHash:e.typeforce.UInt8,wif:e.typeforce.UInt8}),e.Buffer256bit=e.typeforce.BufferN(32),e.Array=e.typeforce.Array,e.Boolean=e.typeforce.Boolean,e.maybe=e.typeforce.maybe})(Ji);var rn={exports:{}},nn={exports:{}},kt={},Er={};Er.byteLength=lf;Er.toByteArray=df;Er.fromByteArray=yf;var Ue=[],Re=[],uf=typeof Uint8Array<"u"?Uint8Array:Array,Dr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(var wt=0,cf=Dr.length;wt<cf;++wt)Ue[wt]=Dr[wt],Re[Dr.charCodeAt(wt)]=wt;Re[45]=62;Re[95]=63;function rs(e){var t=e.length;if(t%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var r=e.indexOf("=");r===-1&&(r=t);var n=r===t?0:4-r%4;return[r,n]}function lf(e){var t=rs(e),r=t[0],n=t[1];return(r+n)*3/4-n}function hf(e,t,r){return(t+r)*3/4-r}function df(e){var t,r=rs(e),n=r[0],i=r[1],a=new uf(hf(e,n,i)),f=0,u=i>0?n-4:n,l;for(l=0;l<u;l+=4)t=Re[e.charCodeAt(l)]<<18|Re[e.charCodeAt(l+1)]<<12|Re[e.charCodeAt(l+2)]<<6|Re[e.charCodeAt(l+3)],a[f++]=t>>16&255,a[f++]=t>>8&255,a[f++]=t&255;return i===2&&(t=Re[e.charCodeAt(l)]<<2|Re[e.charCodeAt(l+1)]>>4,a[f++]=t&255),i===1&&(t=Re[e.charCodeAt(l)]<<10|Re[e.charCodeAt(l+1)]<<4|Re[e.charCodeAt(l+2)]>>2,a[f++]=t>>8&255,a[f++]=t&255),a}function pf(e){return Ue[e>>18&63]+Ue[e>>12&63]+Ue[e>>6&63]+Ue[e&63]}function bf(e,t,r){for(var n,i=[],a=t;a<r;a+=3)n=(e[a]<<16&16711680)+(e[a+1]<<8&65280)+(e[a+2]&255),i.push(pf(n));return i.join("")}function yf(e){for(var t,r=e.length,n=r%3,i=[],a=16383,f=0,u=r-n;f<u;f+=a)i.push(bf(e,f,f+a>u?u:f+a));return n===1?(t=e[r-1],i.push(Ue[t>>2]+Ue[t<<4&63]+"==")):n===2&&(t=(e[r-2]<<8)+e[r-1],i.push(Ue[t>>10]+Ue[t>>4&63]+Ue[t<<2&63]+"=")),i.join("")}var Sn={};/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */Sn.read=function(e,t,r,n,i){var a,f,u=i*8-n-1,l=(1<<u)-1,b=l>>1,g=-7,m=r?i-1:0,v=r?-1:1,A=e[t+m];for(m+=v,a=A&(1<<-g)-1,A>>=-g,g+=u;g>0;a=a*256+e[t+m],m+=v,g-=8);for(f=a&(1<<-g)-1,a>>=-g,g+=n;g>0;f=f*256+e[t+m],m+=v,g-=8);if(a===0)a=1-b;else{if(a===l)return f?NaN:(A?-1:1)*(1/0);f=f+Math.pow(2,n),a=a-b}return(A?-1:1)*f*Math.pow(2,a-n)};Sn.write=function(e,t,r,n,i,a){var f,u,l,b=a*8-i-1,g=(1<<b)-1,m=g>>1,v=i===23?Math.pow(2,-24)-Math.pow(2,-77):0,A=n?0:a-1,B=n?1:-1,P=t<0||t===0&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(u=isNaN(t)?1:0,f=g):(f=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-f))<1&&(f--,l*=2),f+m>=1?t+=v/l:t+=v*Math.pow(2,1-m),t*l>=2&&(f++,l/=2),f+m>=g?(u=0,f=g):f+m>=1?(u=(t*l-1)*Math.pow(2,i),f=f+m):(u=t*Math.pow(2,m-1)*Math.pow(2,i),f=0));i>=8;e[r+A]=u&255,A+=B,u/=256,i-=8);for(f=f<<i|u,b+=i;b>0;e[r+A]=f&255,A+=B,f/=256,b-=8);e[r+A-B]|=P*128};/*!
26
26
  * The buffer module from node.js, for the browser.
package/dist/index.js CHANGED
@@ -2810,7 +2810,7 @@ class cf {
2810
2810
  }
2811
2811
  class Sl {
2812
2812
  constructor(t) {
2813
- if (this.eventListeners = /* @__PURE__ */ new Map(), this.getOrderThreshold = 20, this.useRelay = !0, this.orderBook = new Ys({
2813
+ if (this.eventListeners = /* @__PURE__ */ new Map(), this.getOrderThreshold = 20, this.useRelay = !0, this.refundSacpCache = /* @__PURE__ */ new Map(), this.orderBook = new Ys({
2814
2814
  url: t.orderbookURl,
2815
2815
  walletClient: t.wallets.evmWallet,
2816
2816
  auth: t.auth
@@ -2934,38 +2934,13 @@ class Sl {
2934
2934
  this.emit("onPendingOrdersChanged", i);
2935
2935
  for (let a = 0; a < i.length; a++) {
2936
2936
  const f = i[a], u = es(f.status);
2937
- if (this.emit(
2938
- "log",
2939
- f.create_order.create_id,
2940
- `status: ${f.status}`
2941
- ), Ot(f.source_swap.chain) && f.status === te.InitiateDetected) {
2937
+ if (Ot(f.source_swap.chain) && f.status === te.InitiateDetected) {
2942
2938
  const l = this.getWallet(f.source_swap.chain);
2943
2939
  if (l.error) {
2944
2940
  this.emit("error", f, l.error);
2945
2941
  continue;
2946
2942
  }
2947
- const b = await Vt.from(
2948
- l.val,
2949
- Number(f.source_swap.amount),
2950
- f.create_order.secret_hash,
2951
- it(f.source_swap.initiator),
2952
- it(f.source_swap.redeemer),
2953
- f.source_swap.timelock
2954
- ), g = f.create_order.additional_data.bitcoin_optional_recipient;
2955
- if (g)
2956
- try {
2957
- const m = await b.generateInstantRefundSACP(
2958
- g
2959
- ), v = this.orderbookUrl + "/orders/add-instant-refund-sacp";
2960
- await ot.post(v, {
2961
- body: JSON.stringify({
2962
- order_id: f.create_order.create_id,
2963
- instant_refund_tx_bytes: m
2964
- })
2965
- });
2966
- } catch (m) {
2967
- this.emit("error", f, "Failed to generate SACP: " + m);
2968
- }
2943
+ await this.postRefundSACP(f, l.val);
2969
2944
  }
2970
2945
  switch (u) {
2971
2946
  case le.Redeem: {
@@ -3165,6 +3140,38 @@ class Sl {
3165
3140
  return N("Unsupported chain for wallet");
3166
3141
  }
3167
3142
  }
3143
+ async postRefundSACP(t, r) {
3144
+ const n = this.refundSacpCache.get(t.create_order.create_id);
3145
+ if ((n == null ? void 0 : n.initTxHash) === t.source_swap.initiate_tx_hash) return;
3146
+ const i = await Vt.from(
3147
+ r,
3148
+ Number(t.source_swap.amount),
3149
+ t.create_order.secret_hash,
3150
+ it(t.source_swap.initiator),
3151
+ it(t.source_swap.redeemer),
3152
+ t.source_swap.timelock
3153
+ ), a = t.create_order.additional_data.bitcoin_optional_recipient;
3154
+ if (a)
3155
+ try {
3156
+ const f = await i.generateInstantRefundSACP(
3157
+ a
3158
+ ), u = this.orderbookUrl + "/orders/add-instant-refund-sacp";
3159
+ (await ot.post(u, {
3160
+ headers: {
3161
+ "Content-Type": "application/json"
3162
+ },
3163
+ body: JSON.stringify({
3164
+ order_id: t.create_order.create_id,
3165
+ instant_refund_tx_bytes: f
3166
+ })
3167
+ })).status === "Ok" && this.refundSacpCache.set(t.create_order.create_id, {
3168
+ initTxHash: t.source_swap.initiate_tx_hash
3169
+ });
3170
+ } catch (f) {
3171
+ this.emit("error", t, "Failed to generate and post SACP: " + f);
3172
+ return;
3173
+ }
3174
+ }
3168
3175
  emit(t, ...r) {
3169
3176
  (this.eventListeners.get(t) ?? []).forEach((i) => {
3170
3177
  i(...r);
@@ -21,6 +21,7 @@ export declare class Garden implements IGardenJS {
21
21
  private evmAddress;
22
22
  private orderExecutorCache;
23
23
  private blockNumberFetcher;
24
+ private refundSacpCache;
24
25
  constructor(config: {
25
26
  orderbookURl: string;
26
27
  secretManager: ISecretManager;
@@ -43,6 +44,7 @@ export declare class Garden implements IGardenJS {
43
44
  private btcRedeem;
44
45
  private btcRefund;
45
46
  private getWallet;
47
+ private postRefundSACP;
46
48
  private emit;
47
49
  on<E extends keyof GardenEvents>(event: E, cb: GardenEvents[E]): void;
48
50
  off<E extends keyof GardenEvents>(event: E, cb: GardenEvents[E]): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gardenfi/core",
3
- "version": "0.3.0-beta.7",
3
+ "version": "0.3.0-beta.9",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"