@gardenfi/core 0.1.0
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/CHANGELOG.md +7 -0
- package/README.md +67 -0
- package/dist/index.cjs +1 -0
- package/dist/index.js +1 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/lib/catalogActions.d.ts +3 -0
- package/dist/src/lib/errors.d.ts +9 -0
- package/dist/src/lib/garden.d.ts +27 -0
- package/dist/src/lib/garden.types.d.ts +52 -0
- package/dist/src/lib/swapper.d.ts +35 -0
- package/dist/src/lib/testUtils.d.ts +25 -0
- package/dist/src/lib/utils.d.ts +4 -0
- package/package.json +44 -0
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# @catalogfi/catalog
|
|
2
|
+
|
|
3
|
+
The `@catalogfi/catalog` package serves as an abstraction layer over the `@catalogfi/wallets` and `@catalogfi/orderbook` packages. It provides a simple interface to perform atomic swaps.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
npm install `@catalogfi/catalog`
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
For more information regarding using the library in different environments see [setup](https://github.com/catalogfi/catalog.js-v2/tree/main/packages/catalog#setup).
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
1. Creating an atomic swap: ([should create an order with valid parameters](https://github.com/catalogfi/catalog.js-v2/blob/3019559e8857bf0b54b0c3affcdcad580b868947/packages/catalog/src/lib/catalog.spec.ts#L91))
|
|
16
|
+
2. Interacting with created orders: ([should initiate and redeem](https://github.com/catalogfi/catalog.js-v2/blob/3019559e8857bf0b54b0c3affcdcad580b868947/packages/catalog/src/lib/catalog.spec.ts#L107))
|
|
17
|
+
|
|
18
|
+
## Setup
|
|
19
|
+
|
|
20
|
+
### Node
|
|
21
|
+
|
|
22
|
+
No extra setup is required as both `cjs` and `esm` modules are supported.
|
|
23
|
+
|
|
24
|
+
### Vite
|
|
25
|
+
|
|
26
|
+
Install the vite plugins:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
npm install vite-plugin-wasm vite-plugin-node-polyfills --save-dev
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
and update your `vite.config.ts` as follows:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
import { defineConfig } from "vite";
|
|
36
|
+
import wasm from "vite-plugin-wasm";
|
|
37
|
+
import { nodePolyfills } from "vite-plugin-node-polyfills";
|
|
38
|
+
|
|
39
|
+
export default defineConfig({
|
|
40
|
+
plugins: [
|
|
41
|
+
nodePolyfills(),
|
|
42
|
+
wasm(),
|
|
43
|
+
//other plugins
|
|
44
|
+
],
|
|
45
|
+
//other settings
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Webpack
|
|
50
|
+
|
|
51
|
+
If you're using webpack with a framework like next, then in your webpack config, (if you're using NextJS, this can be found in `next.config.js` ) add support for wasm as shown below:
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
/** @type {import('next').NextConfig} */
|
|
55
|
+
const nextConfig = {
|
|
56
|
+
//other nextConfig options
|
|
57
|
+
webpack: function (config, options) {
|
|
58
|
+
//other webpack config options
|
|
59
|
+
config.experiments = {
|
|
60
|
+
...config.experiments,
|
|
61
|
+
asyncWebAssembly: true,
|
|
62
|
+
};
|
|
63
|
+
return config;
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
module.exports = nextConfig;
|
|
67
|
+
```
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("ethers"),c=require("@gardenfi/orderbook"),u=require("@catalogfi/utils"),S=async(e,t,r,o)=>{const i=r[e],n=r[t];if(!n)throw new Error(`No ${e} wallet found`);if(!i)throw new Error(`No ${t} wallet found`);let d;if(w(e)){const s=h.sha256(u.with0x(Buffer.from("catalog.js"+o+await n.getAddress()).toString("hex"))).slice(2);d=await i.sign(s)}else{const s=h.sha256(u.with0x(Buffer.from("catalog.js"+o+await i.getAddress()).toString("hex"))).slice(2);d=await n.sign(s)}return u.trim0x(h.sha256(u.with0x(d)))},w=e=>e==="bitcoin"||e==="bitcoin_testnet"||e==="bitcoin_regtest",m={WALLET_NOT_FOUND:e=>`${e?"from":"to"} wallet not found`,CHAIN_WALLET_NOT_FOUND:e=>`no ${e} wallet found`},p={NO_ACTION:"no actions can be performed in this state",NO_SECRET:"secret not found in order",INVALID_ACTION:(e,t)=>`can not ${e} on status: ${t}`};class _{constructor(t,r){this.order=t,this.wallets=r}get action(){return c.parseStatus(this.order)}get status(){return+`${this.order.status}${this.order.initiatorAtomicSwap.swapStatus}${this.order.followerAtomicSwap.swapStatus}`}async next(){switch(v[this.action]){case"Initiate":return await this.init();case"Redeem":return await this.redeem();case"Refund":return await this.refund();default:return L}}async init(){switch(this.action){case c.Actions.UserCanInitiate:{const t=this.wallets[this.order.initiatorAtomicSwap.chain];if(!t)throw new Error(`No ${this.order.initiatorAtomicSwap.chain} wallet found`);return{user:"initiator",action:"Initiate",output:await(await l(t,this.order,"native",this.order.initiatorAtomicSwap.asset)).init()}}case c.Actions.CounterpartyCanInitiate:{const t=this.wallets[this.order.followerAtomicSwap.chain];if(!t)throw new Error(`No ${this.order.followerAtomicSwap.chain} wallet`);return{user:"redeemer",action:"Initiate",output:await(await l(t,this.order,"foreign",this.order.followerAtomicSwap.asset)).init()}}default:throw new Error(p.INVALID_ACTION("init",this.status))}}async redeem(){const t=this.getWallet(this.order.followerAtomicSwap.chain),r=this.getWallet(this.order.initiatorAtomicSwap.chain);switch(this.action){case c.Actions.UserCanRedeem:{const o=await l(t,this.order,"foreign",this.order.followerAtomicSwap.asset),i=await S(this.order.initiatorAtomicSwap.chain,this.order.followerAtomicSwap.chain,this.wallets,this.order.secretNonce);return console.log("secret when redeeming: ",i),{user:"initiator",action:"Redeem",output:await o.redeem(i,this.order.userBtcWalletAddress)}}case c.Actions.CounterpartyCanRedeem:{if(!this.order.secret)throw new Error("Secret not found in order");return{user:"redeemer",action:"Redeem",output:await(await l(r,this.order,"native",this.order.initiatorAtomicSwap.asset)).redeem(this.order.secret)}}default:throw new Error(p.INVALID_ACTION("redeem",this.status))}}async refund(){const t=this.getWallet(this.order.initiatorAtomicSwap.chain),r=this.getWallet(this.order.followerAtomicSwap.chain);if(this.order.initiatorAtomicSwap.swapStatus===3)return{user:"initiator",action:"Refund",output:await(await l(t,this.order,"native",this.order.initiatorAtomicSwap.asset)).refund(this.order.userBtcWalletAddress)};if(this.order.followerAtomicSwap.swapStatus===3)return{user:"redeemer",action:"Refund",output:await(await l(r,this.order,"foreign",this.order.followerAtomicSwap.asset)).refund(this.order.userBtcWalletAddress)};throw new Error(p.INVALID_ACTION("refund",this.status))}id(){throw new Error("Method not implemented.")}getWallet(t){const r=this.wallets[t];if(!r)throw new Error(`No ${t} wallet found`);return r}}const l=async(e,t,r,o)=>{console.log(r,o);const i=r==="native"?t.initiatorAtomicSwap:t.followerAtomicSwap;return e.newSwap({recipientAddress:i.redeemerAddress,refundAddress:i.initiatorAddress,initiatorAddress:i.initiatorAddress,chain:c.chainToId[i.chain],expiryBlocks:+i.timelock,secretHash:t.secretHash,amount:+i.amount,contractAddress:o})};var I=(e=>(e.INITIATOR="initiator",e.REDEEMER="redeemer",e))(I||{}),N=(e=>(e.Init="Initiate",e.Redeem="Redeem",e.Refund="Refund",e.None="None",e))(N||{});const v={[c.Actions.UserCanInitiate]:"Initiate",[c.Actions.CounterpartyCanInitiate]:"Initiate",[c.Actions.UserCanRedeem]:"Redeem",[c.Actions.CounterpartyCanRedeem]:"Redeem",[c.Actions.UserCanRefund]:"Refund",[c.Actions.CounterpartyCanRefund]:"Refund",[c.Actions.NoAction]:"None"},L={user:"initiator",action:"None",output:""};class ${constructor(t){if(t)this.extensionId=t.id;else if(x())this.extensionId=g("chrome");else if(E())this.extensionId=g("window");else throw new Error("Catalog wallet extension not found")}send(t,r){return new Promise((o,i)=>{const n={url:"",favicon:""},d=window.location.href.split("://")[1].replace(/\/$/,"");n.url=d;let s=document.querySelector("link[rel='icon']");if(s||(s=document.querySelector("link[rel='shortcut icon']")),s||(s=document.querySelector("link[rel='apple-touch-icon']")),s||(s=document.querySelector("meta[property='og:image']")),s)n.favicon=s instanceof HTMLMetaElement?s.content:s.href;else{const a=new URL(window.location.href);n.favicon=`${a.protocol}//${a.hostname}/favicon.ico`}chrome.runtime.sendMessage(this.extensionId,{method:t,params:r,metadata:n},a=>chrome.runtime.lastError?i(chrome.runtime.lastError):typeof a=="object"&&a&&"error"in a?i(a.error):o(a))})}}const E=()=>{try{const e=window;return e&&e.catalog&&e.catalog.id}catch{return!1}},g=e=>{if(e==="chrome")return chrome.runtime.id;if(e==="window")return window.catalog.id;throw new Error("Invalid medium to get wallet id")},x=()=>{try{return chrome&&!!chrome.runtime&&!!chrome.runtime.id}catch{return!1}},O={createOrderAndSwap:"createOrderAndSwap"};class D{constructor(t,r){this.orderbook=t,this.wallets=r}subscribeOrders(t,r){this.orderbook.subscribeOrders(t,r)}unsubscribeOrders(){return this.orderbook.unsubscribeOrders()}async swap(t,r,o,i,n){if(E()){const T=await new $().send(O.createOrderAndSwap,{from:t,to:r,amt:o,receiveAmount:i,opts:n});return Number(T)}const d=this.wallets[t.chain],s=this.wallets[r.chain];if(!d)throw new Error(m.WALLET_NOT_FOUND(!0));if(!s)throw new Error(m.WALLET_NOT_FOUND(!1));U(t.chain,r.chain),(n&&!n.btcInputAddress||!n)&&(n=n||{},n.btcInputAddress=await this.wallets[w(t.chain)?t.chain:r.chain].getAddress());const a=w(t.chain),A=a?s:d,f=a?d:s,W=await A.getAddress(),b=await this.orderbook.getOrders(W),R=a?await f.getAddress():await A.getAddress(),C=a?await A.getAddress():await f.getAddress(),y=await S(t.chain,r.chain,this.wallets,b.length+1);return this.orderbook.createOrder({fromAsset:t,toAsset:r,sendAmount:o.toString(),receiveAmount:i.toString(),receiveAddress:C,sendAddress:R,secretHash:h.sha256(u.with0x(y)),btcInputAddress:n.btcInputAddress??await f.getAddress()})}getSwap(t){return new _(t,this.wallets)}calculateReceiveAmt(t,r,o){return Promise.resolve(o-o*.03)}}const U=(e,t)=>{if(w(e)===w(t))throw new Error(w(e)?m.CHAIN_WALLET_NOT_FOUND("Bitcoin"):m.CHAIN_WALLET_NOT_FOUND("EVM"))};exports.GardenJS=D;exports.SwapperActions=N;exports.SwapperRole=I;exports.catalogWalletActions=O;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{sha256 as l}from"ethers";import{Actions as c,parseStatus as L,chainToId as v}from"@gardenfi/orderbook";import{with0x as u,trim0x as W}from"@catalogfi/utils";const S=async(e,t,r,a)=>{const i=r[e],s=r[t];if(!s)throw new Error(`No ${e} wallet found`);if(!i)throw new Error(`No ${t} wallet found`);let d;if(w(e)){const o=l(u(Buffer.from("catalog.js"+a+await s.getAddress()).toString("hex"))).slice(2);d=await i.sign(o)}else{const o=l(u(Buffer.from("catalog.js"+a+await i.getAddress()).toString("hex"))).slice(2);d=await s.sign(o)}return W(l(u(d)))},w=e=>e==="bitcoin"||e==="bitcoin_testnet"||e==="bitcoin_regtest",m={WALLET_NOT_FOUND:e=>`${e?"from":"to"} wallet not found`,CHAIN_WALLET_NOT_FOUND:e=>`no ${e} wallet found`},p={NO_ACTION:"no actions can be performed in this state",NO_SECRET:"secret not found in order",INVALID_ACTION:(e,t)=>`can not ${e} on status: ${t}`};class ${constructor(t,r){this.order=t,this.wallets=r}get action(){return L(this.order)}get status(){return+`${this.order.status}${this.order.initiatorAtomicSwap.swapStatus}${this.order.followerAtomicSwap.swapStatus}`}async next(){switch(x[this.action]){case"Initiate":return await this.init();case"Redeem":return await this.redeem();case"Refund":return await this.refund();default:return U}}async init(){switch(this.action){case c.UserCanInitiate:{const t=this.wallets[this.order.initiatorAtomicSwap.chain];if(!t)throw new Error(`No ${this.order.initiatorAtomicSwap.chain} wallet found`);return{user:"initiator",action:"Initiate",output:await(await h(t,this.order,"native",this.order.initiatorAtomicSwap.asset)).init()}}case c.CounterpartyCanInitiate:{const t=this.wallets[this.order.followerAtomicSwap.chain];if(!t)throw new Error(`No ${this.order.followerAtomicSwap.chain} wallet`);return{user:"redeemer",action:"Initiate",output:await(await h(t,this.order,"foreign",this.order.followerAtomicSwap.asset)).init()}}default:throw new Error(p.INVALID_ACTION("init",this.status))}}async redeem(){const t=this.getWallet(this.order.followerAtomicSwap.chain),r=this.getWallet(this.order.initiatorAtomicSwap.chain);switch(this.action){case c.UserCanRedeem:{const a=await h(t,this.order,"foreign",this.order.followerAtomicSwap.asset),i=await S(this.order.initiatorAtomicSwap.chain,this.order.followerAtomicSwap.chain,this.wallets,this.order.secretNonce);return console.log("secret when redeeming: ",i),{user:"initiator",action:"Redeem",output:await a.redeem(i,this.order.userBtcWalletAddress)}}case c.CounterpartyCanRedeem:{if(!this.order.secret)throw new Error("Secret not found in order");return{user:"redeemer",action:"Redeem",output:await(await h(r,this.order,"native",this.order.initiatorAtomicSwap.asset)).redeem(this.order.secret)}}default:throw new Error(p.INVALID_ACTION("redeem",this.status))}}async refund(){const t=this.getWallet(this.order.initiatorAtomicSwap.chain),r=this.getWallet(this.order.followerAtomicSwap.chain);if(this.order.initiatorAtomicSwap.swapStatus===3)return{user:"initiator",action:"Refund",output:await(await h(t,this.order,"native",this.order.initiatorAtomicSwap.asset)).refund(this.order.userBtcWalletAddress)};if(this.order.followerAtomicSwap.swapStatus===3)return{user:"redeemer",action:"Refund",output:await(await h(r,this.order,"foreign",this.order.followerAtomicSwap.asset)).refund(this.order.userBtcWalletAddress)};throw new Error(p.INVALID_ACTION("refund",this.status))}id(){throw new Error("Method not implemented.")}getWallet(t){const r=this.wallets[t];if(!r)throw new Error(`No ${t} wallet found`);return r}}const h=async(e,t,r,a)=>{console.log(r,a);const i=r==="native"?t.initiatorAtomicSwap:t.followerAtomicSwap;return e.newSwap({recipientAddress:i.redeemerAddress,refundAddress:i.initiatorAddress,initiatorAddress:i.initiatorAddress,chain:v[i.chain],expiryBlocks:+i.timelock,secretHash:t.secretHash,amount:+i.amount,contractAddress:a})};var g=(e=>(e.INITIATOR="initiator",e.REDEEMER="redeemer",e))(g||{}),I=(e=>(e.Init="Initiate",e.Redeem="Redeem",e.Refund="Refund",e.None="None",e))(I||{});const x={[c.UserCanInitiate]:"Initiate",[c.CounterpartyCanInitiate]:"Initiate",[c.UserCanRedeem]:"Redeem",[c.CounterpartyCanRedeem]:"Redeem",[c.UserCanRefund]:"Refund",[c.CounterpartyCanRefund]:"Refund",[c.NoAction]:"None"},U={user:"initiator",action:"None",output:""};class D{constructor(t){if(t)this.extensionId=t.id;else if(k())this.extensionId=E("chrome");else if(N())this.extensionId=E("window");else throw new Error("Catalog wallet extension not found")}send(t,r){return new Promise((a,i)=>{const s={url:"",favicon:""},d=window.location.href.split("://")[1].replace(/\/$/,"");s.url=d;let o=document.querySelector("link[rel='icon']");if(o||(o=document.querySelector("link[rel='shortcut icon']")),o||(o=document.querySelector("link[rel='apple-touch-icon']")),o||(o=document.querySelector("meta[property='og:image']")),o)s.favicon=o instanceof HTMLMetaElement?o.content:o.href;else{const n=new URL(window.location.href);s.favicon=`${n.protocol}//${n.hostname}/favicon.ico`}chrome.runtime.sendMessage(this.extensionId,{method:t,params:r,metadata:s},n=>chrome.runtime.lastError?i(chrome.runtime.lastError):typeof n=="object"&&n&&"error"in n?i(n.error):a(n))})}}const N=()=>{try{const e=window;return e&&e.catalog&&e.catalog.id}catch{return!1}},E=e=>{if(e==="chrome")return chrome.runtime.id;if(e==="window")return window.catalog.id;throw new Error("Invalid medium to get wallet id")},k=()=>{try{return chrome&&!!chrome.runtime&&!!chrome.runtime.id}catch{return!1}},O={createOrderAndSwap:"createOrderAndSwap"};class B{constructor(t,r){this.orderbook=t,this.wallets=r}subscribeOrders(t,r){this.orderbook.subscribeOrders(t,r)}unsubscribeOrders(){return this.orderbook.unsubscribeOrders()}async swap(t,r,a,i,s){if(N()){const y=await new D().send(O.createOrderAndSwap,{from:t,to:r,amt:a,receiveAmount:i,opts:s});return Number(y)}const d=this.wallets[t.chain],o=this.wallets[r.chain];if(!d)throw new Error(m.WALLET_NOT_FOUND(!0));if(!o)throw new Error(m.WALLET_NOT_FOUND(!1));H(t.chain,r.chain),(s&&!s.btcInputAddress||!s)&&(s=s||{},s.btcInputAddress=await this.wallets[w(t.chain)?t.chain:r.chain].getAddress());const n=w(t.chain),f=n?o:d,A=n?d:o,R=await f.getAddress(),C=await this.orderbook.getOrders(R),b=n?await A.getAddress():await f.getAddress(),_=n?await f.getAddress():await A.getAddress(),T=await S(t.chain,r.chain,this.wallets,C.length+1);return this.orderbook.createOrder({fromAsset:t,toAsset:r,sendAmount:a.toString(),receiveAmount:i.toString(),receiveAddress:_,sendAddress:b,secretHash:l(u(T)),btcInputAddress:s.btcInputAddress??await A.getAddress()})}getSwap(t){return new $(t,this.wallets)}calculateReceiveAmt(t,r,a){return Promise.resolve(a-a*.03)}}const H=(e,t)=>{if(w(e)===w(t))throw new Error(w(e)?m.CHAIN_WALLET_NOT_FOUND("Bitcoin"):m.CHAIN_WALLET_NOT_FOUND("EVM"))};export{B as GardenJS,I as SwapperActions,g as SwapperRole,O as catalogWalletActions};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const CatalogErrors: {
|
|
2
|
+
WALLET_NOT_FOUND: (from: boolean) => string;
|
|
3
|
+
CHAIN_WALLET_NOT_FOUND: (blockchain: 'EVM' | 'Bitcoin') => string;
|
|
4
|
+
};
|
|
5
|
+
export declare const SwapperErrors: {
|
|
6
|
+
NO_ACTION: string;
|
|
7
|
+
NO_SECRET: string;
|
|
8
|
+
INVALID_ACTION: (action: 'init' | 'redeem' | 'refund', status: number) => string;
|
|
9
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Orders, Order, Asset } from "@gardenfi/orderbook";
|
|
2
|
+
import type { IOrderbook } from "@gardenfi/orderbook";
|
|
3
|
+
import { ISwapper } from "./swapper";
|
|
4
|
+
import { IGardenJS, Wallets } from "./garden.types";
|
|
5
|
+
/**
|
|
6
|
+
* @class
|
|
7
|
+
* @implements {ICatalogJS}
|
|
8
|
+
*/
|
|
9
|
+
export declare class GardenJS implements IGardenJS {
|
|
10
|
+
private readonly orderbook;
|
|
11
|
+
private readonly wallets;
|
|
12
|
+
/**
|
|
13
|
+
* @constructor
|
|
14
|
+
*
|
|
15
|
+
* @param {IOrderbook} orderbook - The orderbook you want to connect to
|
|
16
|
+
* @param {Partial<Wallets>} wallets - Each field in the wallet corresponds to the chain name and it's corresponding value is the wallet
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
constructor(orderbook: IOrderbook, wallets: Partial<Wallets>);
|
|
20
|
+
subscribeOrders(address: string, callback: (orders: Orders) => void): void;
|
|
21
|
+
unsubscribeOrders(): void;
|
|
22
|
+
swap(from: Asset, to: Asset, amt: number, receiveAmount: number, opts?: {
|
|
23
|
+
btcInputAddress?: string;
|
|
24
|
+
}): Promise<number>;
|
|
25
|
+
getSwap(order: Order): ISwapper;
|
|
26
|
+
calculateReceiveAmt(from: Asset, to: Asset, sendAmt: number): Promise<number>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Asset, Chain, EvmChain, Order, Orders } from "@gardenfi/orderbook";
|
|
2
|
+
import { IBitcoinWallet, IEVMWallet } from "@catalogfi/wallets";
|
|
3
|
+
import { ISwapper } from "./swapper";
|
|
4
|
+
export interface IGardenJS {
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* Creates an order
|
|
8
|
+
*
|
|
9
|
+
* @method
|
|
10
|
+
* @param {Asset} from - The asset you want to swap from
|
|
11
|
+
* @param {Asset} to - The asset you want to swap to
|
|
12
|
+
* @param {number} amt - The amount you want to swap in it's lowest denomination
|
|
13
|
+
* @param {number} receiveAmount - The amount you want to receive in it's lowest denomination
|
|
14
|
+
* @param {Object} [opts] - Additional options for creating an order
|
|
15
|
+
* @param {string} [opts.btcInputAddress] - If specified, BTC will be sent to this address
|
|
16
|
+
* @returns {Promise<number>} The order ID
|
|
17
|
+
*/
|
|
18
|
+
swap(from: Asset, to: Asset, amt: number, receiveAmount: number, opts?: {
|
|
19
|
+
btcInputAddress?: string;
|
|
20
|
+
}): Promise<number>;
|
|
21
|
+
/**
|
|
22
|
+
* Calculates the amount you receive. Currently deducts 0.3% of the amount you send.
|
|
23
|
+
*/
|
|
24
|
+
calculateReceiveAmt(from: Asset, to: Asset, sendAmt: number): Promise<number>;
|
|
25
|
+
/**
|
|
26
|
+
* Subscribes to order updates
|
|
27
|
+
*
|
|
28
|
+
* @method
|
|
29
|
+
* @param {string} address - The address to subscribe to, currently each CatalogJS instance can only connect to a single address
|
|
30
|
+
* @param {(orders: Orders) => void} callback - The callback to call when the orders are updated. The first response are all the orders created by a given address
|
|
31
|
+
*
|
|
32
|
+
* @returns {void}
|
|
33
|
+
*/
|
|
34
|
+
subscribeOrders(address: string, callback: (orders: Orders) => void): void;
|
|
35
|
+
/**
|
|
36
|
+
* Unsubscribes from order updates
|
|
37
|
+
*
|
|
38
|
+
* @method
|
|
39
|
+
* @returns {void}
|
|
40
|
+
*/
|
|
41
|
+
unsubscribeOrders(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Gets the swapper for an order, which allows you to progess (init, redeem, refund) the swap
|
|
44
|
+
*
|
|
45
|
+
* @param {Order} order - The order to get the swapper for
|
|
46
|
+
* @returns {ISwapper} The swapper
|
|
47
|
+
*/
|
|
48
|
+
getSwap(order: Order): ISwapper;
|
|
49
|
+
}
|
|
50
|
+
export type Wallets<T extends Chain = Chain> = {
|
|
51
|
+
[K in T]: K extends EvmChain ? IEVMWallet : IBitcoinWallet;
|
|
52
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Actions, Order } from "@gardenfi/orderbook";
|
|
2
|
+
import { Chain } from "@gardenfi/orderbook";
|
|
3
|
+
import { IBaseWallet } from "@catalogfi/wallets";
|
|
4
|
+
export interface ISwapper {
|
|
5
|
+
id(): string;
|
|
6
|
+
next(): Promise<SwapOutput>;
|
|
7
|
+
}
|
|
8
|
+
export declare class Swapper implements ISwapper {
|
|
9
|
+
private order;
|
|
10
|
+
private wallets;
|
|
11
|
+
constructor(order: Order, wallet: Partial<Record<Chain, IBaseWallet>>);
|
|
12
|
+
get action(): Actions;
|
|
13
|
+
get status(): number;
|
|
14
|
+
next(): Promise<SwapOutput>;
|
|
15
|
+
private init;
|
|
16
|
+
private redeem;
|
|
17
|
+
private refund;
|
|
18
|
+
id(): string;
|
|
19
|
+
private getWallet;
|
|
20
|
+
}
|
|
21
|
+
export declare enum SwapperRole {
|
|
22
|
+
INITIATOR = "initiator",
|
|
23
|
+
REDEEMER = "redeemer"
|
|
24
|
+
}
|
|
25
|
+
export declare enum SwapperActions {
|
|
26
|
+
Init = "Initiate",
|
|
27
|
+
Redeem = "Redeem",
|
|
28
|
+
Refund = "Refund",
|
|
29
|
+
None = "None"
|
|
30
|
+
}
|
|
31
|
+
export type SwapOutput = {
|
|
32
|
+
user: SwapperRole;
|
|
33
|
+
action: SwapperActions;
|
|
34
|
+
output: string;
|
|
35
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Chain, Order } from "@gardenfi/orderbook";
|
|
2
|
+
import { Wallet, JsonRpcProvider } from "ethers";
|
|
3
|
+
export declare const orderFactory: ({ secret, secretHash, userBtcWalletAddress, secretNonce, initiatorTimelock, followerTimelock, initiatorAmount, followerAmount, initiatorInitatorAddress, initiatorRedeemerAddress, followerInitiatorAddress, followerRedeemerAddress, initiatorChain, redeemerChain, initiatorAsset, followerAsset, }: {
|
|
4
|
+
secret: string;
|
|
5
|
+
secretHash: string;
|
|
6
|
+
secretNonce: number;
|
|
7
|
+
userBtcWalletAddress: string;
|
|
8
|
+
initiatorTimelock: string;
|
|
9
|
+
followerTimelock: string;
|
|
10
|
+
initiatorAmount: string;
|
|
11
|
+
followerAmount: string;
|
|
12
|
+
initiatorInitatorAddress: string;
|
|
13
|
+
initiatorRedeemerAddress: string;
|
|
14
|
+
followerInitiatorAddress: string;
|
|
15
|
+
followerRedeemerAddress: string;
|
|
16
|
+
initiatorChain: Chain;
|
|
17
|
+
redeemerChain: Chain;
|
|
18
|
+
initiatorAsset: string;
|
|
19
|
+
followerAsset: string;
|
|
20
|
+
}) => Order;
|
|
21
|
+
export declare const atomicSwapStatus: (secretHash: string, initiator: Wallet) => Promise<{
|
|
22
|
+
initiator: any;
|
|
23
|
+
fulfilled: any;
|
|
24
|
+
}>;
|
|
25
|
+
export declare const fundEvmAddress: (provider: JsonRpcProvider, address: string, amount?: string) => Promise<void>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { IBaseWallet } from "@catalogfi/wallets";
|
|
2
|
+
import { Chain } from "@gardenfi/orderbook";
|
|
3
|
+
export declare const computeSecret: (fromChain: Chain, toChain: Chain, wallets: Partial<Record<Chain, IBaseWallet>>, nonce: number) => Promise<string>;
|
|
4
|
+
export declare const isFromChainBitcoin: (chain: Chain) => boolean;
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gardenfi/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"dependencies": {
|
|
6
|
+
"@catalogfi/utils": "^0.1.0",
|
|
7
|
+
"@catalogfi/wallets": "^0.2.0",
|
|
8
|
+
"@gardenfi/orderbook": "^0.1.0",
|
|
9
|
+
"ethers": "6.8.0"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "vite build",
|
|
16
|
+
"dev": "vite build --watch"
|
|
17
|
+
},
|
|
18
|
+
"main": "./dist/index.cjs",
|
|
19
|
+
"module": "./dist/index.js",
|
|
20
|
+
"typings": "./dist/src/index.d.ts",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"require": "./dist/index.cjs",
|
|
24
|
+
"import": "./dist/index.js",
|
|
25
|
+
"types": "./dist/src/index.d.ts"
|
|
26
|
+
},
|
|
27
|
+
"./package.json": "./package.json"
|
|
28
|
+
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public",
|
|
31
|
+
"registry": "https://registry.npmjs.org/"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/jest": "^29.5.12",
|
|
35
|
+
"dotenv": "^16.3.1",
|
|
36
|
+
"jest": "^29.7.0",
|
|
37
|
+
"typescript": "^5.2.2",
|
|
38
|
+
"vite": "^5.1.6",
|
|
39
|
+
"vite-plugin-dts": "^3.7.3",
|
|
40
|
+
"vite-plugin-top-level-await": "^1.4.1",
|
|
41
|
+
"vite-plugin-wasm": "^3.3.0"
|
|
42
|
+
},
|
|
43
|
+
"sideEffects": false
|
|
44
|
+
}
|