@synfin/widget 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/api.js CHANGED
@@ -25,7 +25,9 @@ function resolveFetch(injected) {
25
25
  if (g === undefined) {
26
26
  throw new SynfinApiError(0, 'network', 'no fetch available in this runtime');
27
27
  }
28
- return g;
28
+ // Bind to globalThis: browsers reject `fetch` called with a detached receiver
29
+ // ("Illegal invocation"). See packages/client/src/http.ts for the full note.
30
+ return g.bind(globalThis);
29
31
  }
30
32
  /**
31
33
  * Fetch a quote. Sends the x-api-key header only when {@link QuoteRequest.apiKey}
@@ -1,5 +1,5 @@
1
- /*! @synfin/widget 0.1.1 | MIT | https://synfin.xyz/docs/sdk */
2
- "use strict";(()=>{var W=Object.defineProperty;var D=(t,n,e)=>n in t?W(t,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[n]=e;var d=(t,n,e)=>D(t,typeof n!="symbol"?n+"":n,e);var p=class extends Error{constructor(e,i,s){super(s);d(this,"status");d(this,"code");this.name="SynfinApiError",this.status=e,this.code=i}};function V(t){if(t!==void 0)return t;let n=globalThis.fetch;if(n===void 0)throw new Error("no global fetch available; pass { fetch } to createClient (Node 18+ and browsers have it built in)");return n}function F(t){let n=[];for(let[e,i]of Object.entries(t))i!==void 0&&n.push(`${encodeURIComponent(e)}=${encodeURIComponent(String(i))}`);return n.length>0?`?${n.join("&")}`:""}async function S(t){let n;try{n=await t.json()}catch{let e=await t.text().catch(()=>"");throw new p(t.status,"bad_response",e.length>0?e:"non-JSON response from the Synfin API")}if(!t.ok){let e=n;throw new p(t.status,e.code??"error",e.error??`HTTP ${t.status}`)}return n}var O="https://synfin.xyz";function E(t){if(t.apiKey===void 0||t.apiKey==="")throw new Error("createClient requires an apiKey");let n={baseUrl:(t.baseUrl??O).replace(/\/+$/,""),apiKey:t.apiKey,fetch:V(t.fetch)};return{getQuote:e=>j(n,e),createPlan:e=>G(n,e)}}async function j(t,n){let e=F({from:n.from,to:n.to,amount:String(n.amount),slippageBps:n.slippageBps,feeBps:n.feeBps,feeRecipient:n.feeRecipient}),i=await t.fetch(`${t.baseUrl}/api/quote${e}`,{method:"GET",headers:{"x-api-key":t.apiKey}});return S(i)}async function G(t,n){let e={from:n.from,to:n.to,amount:String(n.amount),venueId:n.venueId,takerParty:n.takerParty,idempotencyKey:n.idempotencyKey};n.slippageBps!==void 0&&(e.slippageBps=n.slippageBps),n.feeBps!==void 0&&(e.feeBps=n.feeBps),n.feeRecipient!==void 0&&(e.feeRecipient=n.feeRecipient);let i=await t.fetch(`${t.baseUrl}/api/execute/plan`,{method:"POST",headers:{"x-api-key":t.apiKey,"content-type":"application/json"},body:JSON.stringify(e)});return S(i)}function Y(t){let n=[];for(let[e,i]of Object.entries(t))i!==void 0&&n.push(`${encodeURIComponent(e)}=${encodeURIComponent(String(i))}`);return n.length>0?`?${n.join("&")}`:""}function J(t){if(t!==void 0)return t;let n=globalThis.fetch;if(n===void 0)throw new p(0,"network","no fetch available in this runtime");return n}async function P(t,n){let e=Y({from:n.from,to:n.to,amount:String(n.amount),slippageBps:n.slippageBps,feeBps:n.feeBps,feeRecipient:n.feeRecipient}),i={};t.apiKey!==null&&t.apiKey!==""&&(i["x-api-key"]=t.apiKey);let s=await J(t.fetch)(`${t.baseUrl}/api/quote${e}`,{method:"GET",headers:i}),o;try{o=await s.json()}catch{let r=await s.text().catch(()=>"");throw new p(s.status,"bad_response",r.length>0?r:"non-JSON response from the Synfin API")}if(!s.ok){let r=o;throw new p(s.status,r.code??"error",r.error??`HTTP ${s.status}`)}return o}var y=[{symbol:"CC",name:"Canton Coin",instrumentId:"Amulet",decimals:10},{symbol:"USDCx",name:"USDC (interchain)",instrumentId:"USDCx",decimals:6},{symbol:"CBTC",name:"Canton BTC",instrumentId:"CBTC",decimals:8}];function x(t){let n=t.trim().toLowerCase();return y.find(e=>e.symbol.toLowerCase()===n)}function w(t){let n=t.trim(),e=n.toLowerCase(),i=y.find(o=>o.instrumentId.toLowerCase()===e);if(i)return i.symbol;let s=y.find(o=>o.symbol.toLowerCase()===e);return s?s.symbol:n}var X={CC:{label:"CC",hue:20},AMULET:{label:"CC",hue:20},USDCX:{label:"USDC",hue:212},CBTC:{label:"BTC",hue:33},CETH:{label:"ETH",hue:250},CUSD:{label:"USD",hue:150}};function Z(t){let n=0;for(let e=0;e<t.length;e++)n=n*31+t.charCodeAt(e)>>>0;return n%360}function R(t){let n=w(t).toUpperCase(),e=X[n]??{label:n.slice(0,3),hue:Z(n)},i=(e.hue+24)%360,s=`sfic${e.hue}`,o=e.label.length>=4?6.5:e.label.length===3?8:9.5;return`<svg class="asset__icon" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><defs><linearGradient id="${s}" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="hsl(${e.hue} 78% 58%)"></stop><stop offset="1" stop-color="hsl(${i} 72% 44%)"></stop></linearGradient></defs><circle cx="12" cy="12" r="11" fill="url(#${s})"></circle><text x="12" y="12" dy="0.35em" text-anchor="middle" font-size="${o}" font-weight="700" fill="#fff">${e.label}</text></svg>`}function A(t){let n=t.trim().toLowerCase();return n===""?y:y.filter(e=>e.symbol.toLowerCase().includes(n)||e.name.toLowerCase().includes(n))}function g(t,n=6){if(t===null)return"-";if(!/^-?\d+(\.\d+)?$/.test(t))return t;let[e="0",i=""]=t.split(".");if(i==="")return e;let s=i.slice(0,n).replace(/0+$/,"");return s===""?e:`${e}.${s}`}function ee(t,n){let e=/^\d+(\.\d+)?$/;if(!e.test(t)||!e.test(n))return t;let i=_=>{let[K="0",Q=""]=_.split(".");return[K,Q]},[s,o]=i(t),[r,a]=i(n),l=Math.max(o.length,a.length),u=(BigInt(s+o.padEnd(l,"0"))+BigInt(r+a.padEnd(l,"0"))).toString().padStart(l+1,"0"),h=u.slice(0,u.length-l),m=l>0?u.slice(u.length-l):"";return m===""?h:`${h}.${m}`}function B(t){return{service:{label:"Synfin service",bps:t.service.bps,amount:t.service.amount},integrator:t.integrator===null?null:{label:"Integrator fee",bps:t.integrator.bps,amount:t.integrator.amount,partnerShare:t.integrator.partnerShare,synfinShare:t.integrator.synfinShare},userReceives:t.userReceives,total:t.integrator===null?t.service.amount:ee(t.service.amount,t.integrator.amount)}}var I=100,te=15e3;function C(t){let n=[],e=(t.from??"CC").trim(),i=(t.to??"USDCx").trim();x(e)===void 0&&n.push({field:"from",message:`unknown asset "${e}"`}),x(i)===void 0&&n.push({field:"to",message:`unknown asset "${i}"`}),e.toLowerCase()===i.toLowerCase()&&n.push({field:"to",message:"from and to must differ"});let s=(t.amount??"100").trim();(!/^\d+(\.\d+)?$/.test(s)||Number(s)<=0)&&n.push({field:"amount",message:"amount must be a positive number"});let o=null,r=null;if(t.feeBps!==void 0||t.feeRecipient!==void 0)if(t.feeBps===void 0||t.feeRecipient===void 0)n.push({field:"fee",message:"feeBps and feeRecipient must be set together"});else{let m=Number(t.feeBps);!Number.isInteger(m)||m<0||m>I?n.push({field:"feeBps",message:`feeBps must be an integer 0 to ${I}`}):o=m;let _=String(t.feeRecipient).trim();_===""?n.push({field:"feeRecipient",message:"feeRecipient required"}):r=_}let l=t.appearance==="light"?"light":"dark",f=(t.baseUrl??"https://synfin.xyz").replace(/\/+$/,""),u=typeof t.refreshMs=="number"&&t.refreshMs>=3e3?t.refreshMs:te,h=(t.apiKey??"").trim();return{config:{apiKey:h===""?null:h,feeBps:o,feeRecipient:r,from:e,to:i,amount:s,appearance:l,baseUrl:f,refreshMs:u,showFeeBreakdown:t.showFeeBreakdown===!0,showAttribution:t.showAttribution!==!1},issues:n}}var v={quote:"synfin:quote",asset:"synfin:asset",venue:"synfin:venue",plan:"synfin:plan",status:"synfin:status",error:"synfin:error"};function b(t,n,e){t.dispatchEvent(new CustomEvent(n,{detail:e,bubbles:!0,composed:!0}))}function $(t,n){let e=t.venues.filter(i=>i.available);return e.find(i=>i.venueId===n)??t.best??e[0]??null}function c(t){return t.replace(/[&<>"']/g,n=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[n]??n)}function z(t){return t.charAt(0).toUpperCase()+t.slice(1)}function N(t,n,e=null,i=null){switch(t.kind){case"idle":return"";case"loading":return ne();case"invalid":return L("!",t.title,c(t.message),"");case"error":return L("!","Could not load a quote",c(t.message),"error");case"no-route":return L("\u2205","No route right now",`No venue can fill ${c(t.pair.give)} to ${c(t.pair.want)} at this size. Try a different amount or pair.`,"");case"quoted":return ie(t,n,e,i)}}function ne(){return`<div class="quote" aria-busy="true" aria-label="Loading a quote">
1
+ /*! @synfin/widget 0.1.2 | MIT | https://synfin.xyz/docs/sdk */
2
+ "use strict";(()=>{var W=Object.defineProperty;var D=(t,n,e)=>n in t?W(t,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[n]=e;var d=(t,n,e)=>D(t,typeof n!="symbol"?n+"":n,e);var p=class extends Error{constructor(e,i,s){super(s);d(this,"status");d(this,"code");this.name="SynfinApiError",this.status=e,this.code=i}};function V(t){if(t!==void 0)return t;let n=globalThis.fetch;if(n===void 0)throw new Error("no global fetch available; pass { fetch } to createClient (Node 18+ and browsers have it built in)");return n}function F(t){let n=[];for(let[e,i]of Object.entries(t))i!==void 0&&n.push(`${encodeURIComponent(e)}=${encodeURIComponent(String(i))}`);return n.length>0?`?${n.join("&")}`:""}async function S(t){let n;try{n=await t.json()}catch{let e=await t.text().catch(()=>"");throw new p(t.status,"bad_response",e.length>0?e:"non-JSON response from the Synfin API")}if(!t.ok){let e=n;throw new p(t.status,e.code??"error",e.error??`HTTP ${t.status}`)}return n}var O="https://synfin.xyz";function E(t){if(t.apiKey===void 0||t.apiKey==="")throw new Error("createClient requires an apiKey");let n={baseUrl:(t.baseUrl??O).replace(/\/+$/,""),apiKey:t.apiKey,fetch:V(t.fetch)};return{getQuote:e=>j(n,e),createPlan:e=>G(n,e)}}async function j(t,n){let e=F({from:n.from,to:n.to,amount:String(n.amount),slippageBps:n.slippageBps,feeBps:n.feeBps,feeRecipient:n.feeRecipient}),i=await t.fetch(`${t.baseUrl}/api/quote${e}`,{method:"GET",headers:{"x-api-key":t.apiKey}});return S(i)}async function G(t,n){let e={from:n.from,to:n.to,amount:String(n.amount),venueId:n.venueId,takerParty:n.takerParty,idempotencyKey:n.idempotencyKey};n.slippageBps!==void 0&&(e.slippageBps=n.slippageBps),n.feeBps!==void 0&&(e.feeBps=n.feeBps),n.feeRecipient!==void 0&&(e.feeRecipient=n.feeRecipient);let i=await t.fetch(`${t.baseUrl}/api/execute/plan`,{method:"POST",headers:{"x-api-key":t.apiKey,"content-type":"application/json"},body:JSON.stringify(e)});return S(i)}function Y(t){let n=[];for(let[e,i]of Object.entries(t))i!==void 0&&n.push(`${encodeURIComponent(e)}=${encodeURIComponent(String(i))}`);return n.length>0?`?${n.join("&")}`:""}function J(t){if(t!==void 0)return t;let n=globalThis.fetch;if(n===void 0)throw new p(0,"network","no fetch available in this runtime");return n.bind(globalThis)}async function P(t,n){let e=Y({from:n.from,to:n.to,amount:String(n.amount),slippageBps:n.slippageBps,feeBps:n.feeBps,feeRecipient:n.feeRecipient}),i={};t.apiKey!==null&&t.apiKey!==""&&(i["x-api-key"]=t.apiKey);let s=await J(t.fetch)(`${t.baseUrl}/api/quote${e}`,{method:"GET",headers:i}),o;try{o=await s.json()}catch{let r=await s.text().catch(()=>"");throw new p(s.status,"bad_response",r.length>0?r:"non-JSON response from the Synfin API")}if(!s.ok){let r=o;throw new p(s.status,r.code??"error",r.error??`HTTP ${s.status}`)}return o}var y=[{symbol:"CC",name:"Canton Coin",instrumentId:"Amulet",decimals:10},{symbol:"USDCx",name:"USDC (interchain)",instrumentId:"USDCx",decimals:6},{symbol:"CBTC",name:"Canton BTC",instrumentId:"CBTC",decimals:8}];function x(t){let n=t.trim().toLowerCase();return y.find(e=>e.symbol.toLowerCase()===n)}function w(t){let n=t.trim(),e=n.toLowerCase(),i=y.find(o=>o.instrumentId.toLowerCase()===e);if(i)return i.symbol;let s=y.find(o=>o.symbol.toLowerCase()===e);return s?s.symbol:n}var X={CC:{label:"CC",hue:20},AMULET:{label:"CC",hue:20},USDCX:{label:"USDC",hue:212},CBTC:{label:"BTC",hue:33},CETH:{label:"ETH",hue:250},CUSD:{label:"USD",hue:150}};function Z(t){let n=0;for(let e=0;e<t.length;e++)n=n*31+t.charCodeAt(e)>>>0;return n%360}function R(t){let n=w(t).toUpperCase(),e=X[n]??{label:n.slice(0,3),hue:Z(n)},i=(e.hue+24)%360,s=`sfic${e.hue}`,o=e.label.length>=4?6.5:e.label.length===3?8:9.5;return`<svg class="asset__icon" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><defs><linearGradient id="${s}" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="hsl(${e.hue} 78% 58%)"></stop><stop offset="1" stop-color="hsl(${i} 72% 44%)"></stop></linearGradient></defs><circle cx="12" cy="12" r="11" fill="url(#${s})"></circle><text x="12" y="12" dy="0.35em" text-anchor="middle" font-size="${o}" font-weight="700" fill="#fff">${e.label}</text></svg>`}function A(t){let n=t.trim().toLowerCase();return n===""?y:y.filter(e=>e.symbol.toLowerCase().includes(n)||e.name.toLowerCase().includes(n))}function g(t,n=6){if(t===null)return"-";if(!/^-?\d+(\.\d+)?$/.test(t))return t;let[e="0",i=""]=t.split(".");if(i==="")return e;let s=i.slice(0,n).replace(/0+$/,"");return s===""?e:`${e}.${s}`}function ee(t,n){let e=/^\d+(\.\d+)?$/;if(!e.test(t)||!e.test(n))return t;let i=_=>{let[K="0",Q=""]=_.split(".");return[K,Q]},[s,o]=i(t),[r,a]=i(n),l=Math.max(o.length,a.length),u=(BigInt(s+o.padEnd(l,"0"))+BigInt(r+a.padEnd(l,"0"))).toString().padStart(l+1,"0"),h=u.slice(0,u.length-l),m=l>0?u.slice(u.length-l):"";return m===""?h:`${h}.${m}`}function B(t){return{service:{label:"Synfin service",bps:t.service.bps,amount:t.service.amount},integrator:t.integrator===null?null:{label:"Integrator fee",bps:t.integrator.bps,amount:t.integrator.amount,partnerShare:t.integrator.partnerShare,synfinShare:t.integrator.synfinShare},userReceives:t.userReceives,total:t.integrator===null?t.service.amount:ee(t.service.amount,t.integrator.amount)}}var I=100,te=15e3;function C(t){let n=[],e=(t.from??"CC").trim(),i=(t.to??"USDCx").trim();x(e)===void 0&&n.push({field:"from",message:`unknown asset "${e}"`}),x(i)===void 0&&n.push({field:"to",message:`unknown asset "${i}"`}),e.toLowerCase()===i.toLowerCase()&&n.push({field:"to",message:"from and to must differ"});let s=(t.amount??"100").trim();(!/^\d+(\.\d+)?$/.test(s)||Number(s)<=0)&&n.push({field:"amount",message:"amount must be a positive number"});let o=null,r=null;if(t.feeBps!==void 0||t.feeRecipient!==void 0)if(t.feeBps===void 0||t.feeRecipient===void 0)n.push({field:"fee",message:"feeBps and feeRecipient must be set together"});else{let m=Number(t.feeBps);!Number.isInteger(m)||m<0||m>I?n.push({field:"feeBps",message:`feeBps must be an integer 0 to ${I}`}):o=m;let _=String(t.feeRecipient).trim();_===""?n.push({field:"feeRecipient",message:"feeRecipient required"}):r=_}let l=t.appearance==="light"?"light":"dark",f=(t.baseUrl??"https://synfin.xyz").replace(/\/+$/,""),u=typeof t.refreshMs=="number"&&t.refreshMs>=3e3?t.refreshMs:te,h=(t.apiKey??"").trim();return{config:{apiKey:h===""?null:h,feeBps:o,feeRecipient:r,from:e,to:i,amount:s,appearance:l,baseUrl:f,refreshMs:u,showFeeBreakdown:t.showFeeBreakdown===!0,showAttribution:t.showAttribution!==!1},issues:n}}var v={quote:"synfin:quote",asset:"synfin:asset",venue:"synfin:venue",plan:"synfin:plan",status:"synfin:status",error:"synfin:error"};function b(t,n,e){t.dispatchEvent(new CustomEvent(n,{detail:e,bubbles:!0,composed:!0}))}function $(t,n){let e=t.venues.filter(i=>i.available);return e.find(i=>i.venueId===n)??t.best??e[0]??null}function c(t){return t.replace(/[&<>"']/g,n=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[n]??n)}function z(t){return t.charAt(0).toUpperCase()+t.slice(1)}function N(t,n,e=null,i=null){switch(t.kind){case"idle":return"";case"loading":return ne();case"invalid":return L("!",t.title,c(t.message),"");case"error":return L("!","Could not load a quote",c(t.message),"error");case"no-route":return L("\u2205","No route right now",`No venue can fill ${c(t.pair.give)} to ${c(t.pair.want)} at this size. Try a different amount or pair.`,"");case"quoted":return ie(t,n,e,i)}}function ne(){return`<div class="quote" aria-busy="true" aria-label="Loading a quote">
3
3
  <div class="skel skel-big"></div>
4
4
  <div class="skel skel-row"></div>
5
5
  <div class="skel skel-row"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synfin/widget",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "The Synfin widget: an embeddable, framework-agnostic quote-and-fee widget (a <synfin-widget> custom element, plus a React wrapper) built on @synfin/client. Live best-execution quotes across Canton venues with the partner's disclosed fees. Non-custodial: it never holds keys.",
5
5
  "license": "MIT",
6
6
  "type": "module",