@avalabs/bitcoin-module 0.3.1 → 0.4.1

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
@@ -9,9 +9,9 @@ var core = require('@zodios/core');
9
9
  var zod = require('zod');
10
10
  var bitcoinjsLib = require('bitcoinjs-lib');
11
11
 
12
- var ke=Object.defineProperty;var ve=(r,e,t)=>e in r?ke(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var Z=(r,e,t)=>(ve(r,typeof e!="symbol"?e+"":e,t),t),J=(r,e,t)=>{if(!e.has(r))throw TypeError("Cannot "+t)};var c=(r,e,t)=>(J(r,e,"read from private field"),t?t.call(r):e.get(r)),P=(r,e,t)=>{if(e.has(r))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(r):e.set(r,t);},x=(r,e,t,n)=>(J(r,e,"write to private field"),n?n.call(r,t):e.set(r,t),t);var be={glacierApiUrl:"https://glacier-api.avax.network",proxyApiUrl:"https://proxy-api.avax.network"},Re={glacierApiUrl:"https://glacier-api-dev.avax.network",proxyApiUrl:"https://proxy-api-dev.avax.network"},te=r=>{switch(r){case vmModuleTypes.Environment.PRODUCTION:return be;case vmModuleTypes.Environment.DEV:return Re}};var re={name:"Bitcoin",description:"",version:"0.0.1",sources:{module:{checksum:"",location:{npm:{filePath:"dist/bundle.js",packageName:"@avalabs/bitcoin-module",registry:"https://registry.npmjs.org"}}},provider:{checksum:"",location:{npm:{filePath:"dist/provider.js",packageName:"@avalabs/bitcoin-module",registry:"https://registry.npmjs.org"}}}},network:{chainIds:["bip122:000000000019d6689c085ae165831e93","bip122:000000000933ea01ad0ee984209779ba"],namespaces:["bip122"]},cointype:"0",permissions:{rpc:{dapps:!0,methods:["bitcoin_sendTransaction"]}},manifestVersion:"0.0"};var m=({isTestnet:r,proxyApiUrl:e})=>new coreWalletsSdk.BitcoinProvider(!r,void 0,`${e}/proxy/nownodes/${r?"btcbook-testnet":"btcbook"}`,`${e}/proxy/nownodes/${r?"btc-testnet":"btc"}`,process.env.GLACIER_API_KEY?{token:process.env.GLACIER_API_KEY}:{});async function ne({isTestnet:r,proxyApiUrl:e}){let t=m({isTestnet:r,proxyApiUrl:e}),{high:n,low:o,medium:a}=await t.getFeeRates();return {low:{maxFeePerGas:BigInt(o)},medium:{maxFeePerGas:BigInt(a)},high:{maxFeePerGas:BigInt(n)},isFixedFee:!1}}var ae=(r,{address:e,network:t})=>{let{explorerUrl:n,networkToken:o}=t,a=r.addresses[0]??"";return {chainId:t.chainId.toString(),explorerLink:`${n}/tx/${r.hash}`,from:r.isSender?e:a,gasUsed:r.fee.toString(),hash:r.hash,isContractCall:!1,isIncoming:!r.isSender,isOutgoing:r.isSender,isSender:r.isSender,timestamp:r.receivedTime*1e3,to:r.isSender?a:e,tokens:[{amount:(Math.abs(r.amount)/10**o.decimals).toString(),decimal:o.decimals.toString(),name:o.name,symbol:o.symbol,type:vmModuleTypes.TokenType.NATIVE}],txType:r.isSender?vmModuleTypes.TransactionType.SEND:vmModuleTypes.TransactionType.RECEIVE}};var se=async({address:r,network:e,proxyApiUrl:t})=>(await m({isTestnet:!!e.isTestnet,proxyApiUrl:t}).getTxHistory(r)).map(a=>ae(a,{address:r,network:e}));var V=async({operation:r,isSuccess:e,maxRetries:t=10,backoffPolicy:n=B.exponential()})=>{let o=0,a=0,s;for(;a<t;){a>0&&await we(o);try{let i=await r(a);if(e(i))return i}catch(i){s=i;}o=n(a),a++;}let p=s?`Max retry exceeded. ${s}`:"Max retry exceeded.";throw new Error(p)},B=class{static exponential(){return e=>Math.pow(2,e)*1e3}static constant(e){return t=>e*1e3}static constantMs(e){return t=>e}};function we(r){return new Promise(e=>setTimeout(e,r))}var j=r=>V({operation:e=>r(e>0),maxRetries:2,backoffPolicy:B.constant(1),isSuccess:e=>e?.status?.error_code!==429});function ie(r){let e,t=0;for(e=0;e<r.length;e++)t+=r.charCodeAt(e)*(e+1);return t}function Q(r){let e,t=0;for(e=0;e<r.length;e++){let n=ie(r[e]??"");t=t+65027/n;}return (""+t).slice(0,16)}var X=r=>new core.Zodios(`${r}/proxy/coingecko`,[{method:"post",path:"/simple/price",parameters:[{name:"ids",type:"Query",schema:zod.string()},{name:"vs_currencies",type:"Query",schema:zod.string()},{name:"include_market_cap",type:"Query",schema:zod.string().optional()},{name:"include_24hr_vol",type:"Query",schema:zod.string().optional()},{name:"include_24hr_change",type:"Query",schema:zod.string().optional()},{name:"include_last_updated_at",type:"Query",schema:zod.string().optional()}],alias:"simplePrice",response:vmModuleTypes.RawSimplePriceResponseSchema},{method:"post",path:"/simple/token_price/:id",parameters:[{name:"id",type:"Path",schema:zod.string()},{name:"contract_addresses",type:"Query",schema:zod.string().array()},{name:"vs_currencies",type:"Query",schema:zod.string().array()},{name:"include_market_cap",type:"Query",schema:zod.boolean().optional()},{name:"include_24hr_vol",type:"Query",schema:zod.boolean().optional()},{name:"include_24hr_change",type:"Query",schema:zod.boolean().optional()}],alias:"simplePriceByContractAddresses",response:vmModuleTypes.SimplePriceResponseSchema}],{axiosConfig:{headers:{"Content-Type":"application/json"}}});var ce=coreCoingeckoSdk.getBasicCoingeckoHttp(),f,k,w=class{constructor({storage:e,proxyApiUrl:t}){P(this,f,void 0);P(this,k,void 0);Z(this,"transformSimplePriceResponse",(e,t=[coreCoingeckoSdk.VsCurrencyType.USD])=>{let n={};return Object.keys(e).forEach(o=>{let a=e[o];n[o]={},t.forEach(s=>{n[o]={[s]:{price:a?.[s],change24:a?.[`${s}_24h_change`],vol24:a?.[`${s}_24h_vol`],marketCap:a?.[`${s}_market_cap`]}};});}),n});x(this,f,e),x(this,k,t);}async getSimplePrice({coinIds:e=[],currencies:t=[coreCoingeckoSdk.VsCurrencyType.USD]}){let n,a=`getSimplePrice-${e?`${Q(e)}-${t.toString()}`:`${t.toString()}`}`;if(n=c(this,f)?.get?.(a),n)return n;try{n=await j(s=>this.simplePrice({coinIds:e,currencies:t,marketCap:!0,vol24:!0,change24:!0,useCoingeckoProxy:s}));}catch{n=void 0;}return c(this,f)?.set?.(a,n),n}async getPricesByAddresses(e,t,n=coreCoingeckoSdk.VsCurrencyType.USD){let o,s=`getPricesWithMarketDataByAddresses-${`${Q(e)}-${t}-${n}`}`;if(o=c(this,f)?.get?.(s),o)return o;try{o=await j(p=>this.fetchPricesByAddresses({assetPlatformId:t,tokenAddresses:e,currency:n,useCoingeckoProxy:p}));}catch{o=void 0;}return c(this,f)?.set?.(s,o),o}async fetchPricesByAddresses({assetPlatformId:e,tokenAddresses:t,currency:n=coreCoingeckoSdk.VsCurrencyType.USD,useCoingeckoProxy:o=!1}){return o?X(c(this,k)).simplePriceByContractAddresses(void 0,{params:{id:e},queries:{contract_addresses:t,vs_currencies:[n],include_market_cap:!0,include_24hr_vol:!0,include_24hr_change:!0}}):coreCoingeckoSdk.simpleTokenPrice(ce,{assetPlatformId:e,tokenAddresses:t,currencies:[n],marketCap:!0,vol24:!0,change24:!0})}async simplePrice({coinIds:e=[],currencies:t=[coreCoingeckoSdk.VsCurrencyType.USD],marketCap:n=!1,vol24:o=!1,change24:a=!1,lastUpdated:s=!1,useCoingeckoProxy:p=!1,shouldThrow:i=!0}){if(p){let M=await X(c(this,k)).simplePrice(void 0,{queries:{ids:e?.join(","),vs_currencies:t.join(","),include_market_cap:String(n),include_24hr_vol:String(o),include_24hr_change:String(a),include_last_updated_at:String(s)}});return this.transformSimplePriceResponse(M,t)}return coreCoingeckoSdk.simplePrice(ce,{coinIds:e,currencies:t,marketCap:n,vol24:o,change24:a,lastUpdated:s,shouldThrow:i})}};f=new WeakMap,k=new WeakMap;var Fe="https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/usd.min.json",$e="https://latest.currency-api.pages.dev/v1/currencies/usd.min.json",me=zod.object({date:zod.string(),usd:zod.record(zod.number())});new core.Zodios(Fe,[{method:"get",path:"",alias:"getExchangeRates",response:me}]);new core.Zodios($e,[{method:"get",path:"",alias:"getExchangeRates",response:me}]);var z=(r,e,t,n)=>({label:r,type:vmModuleTypes.DetailItemType.CURRENCY,value:e,maxDecimals:t,symbol:n}),K=(r,e,t="horizontal")=>({label:r,alignment:t,type:vmModuleTypes.DetailItemType.TEXT,value:e}),U=(r,e)=>({label:r,type:vmModuleTypes.DetailItemType.ADDRESS,value:e});var le=(r,e,t)=>{let n=t?.[r]?.[e??""]??{};return {priceInCurrency:n.price??void 0,marketCap:n.marketCap??void 0,vol24:n.vol24??void 0,change24:n.change24??void 0}};var N=async({addresses:r,currency:e,network:t,withScripts:n,proxyApiUrl:o,storage:a})=>{let s=m({isTestnet:!!t.isTestnet,proxyApiUrl:o}),p=new w({proxyApiUrl:o,storage:a}),i=t.pricingProviders?.coingecko.nativeTokenId,v=typeof e=="string"&&typeof i=="string"?await p.getSimplePrice({coinIds:[i],currencies:[e]}):void 0,{priceInCurrency:l,change24:b,marketCap:R,vol24:S}=le(i??"",e,v);return (await Promise.allSettled(r.map(async y=>{let{balance:g,utxos:D,balanceUnconfirmed:F,utxosUnconfirmed:$}=await s.getUtxoBalance(y,n),h=new coreUtilsSdk.TokenUnit(g,t.networkToken.decimals,t.networkToken.symbol),T=l!==void 0?h.mul(l):void 0,O=h.toDisplay(),L=new coreUtilsSdk.TokenUnit(F,t.networkToken.decimals,t.networkToken.symbol),Y=l!==void 0?L.mul(l):void 0,xe=t.networkToken.symbol;return {[y]:{[xe]:{...t.networkToken,utxos:D,utxosUnconfirmed:$,coingeckoId:i??"",type:vmModuleTypes.TokenType.NATIVE,balance:h.toSubUnit(),balanceDisplayValue:O,balanceInCurrency:T?.toDisplay({fixedDp:2,asNumber:!0}),balanceCurrencyDisplayValue:T?.toDisplay({fixedDp:2}),priceInCurrency:l,marketCap:R,vol24:S,change24:b,unconfirmedBalance:L.toSubUnit(),unconfirmedBalanceDisplayValue:L.toDisplay(),unconfirmedBalanceInCurrency:Y?.toDisplay({fixedDp:2,asNumber:!0}),unconfirmedBalanceCurrencyDisplayValue:Y?.toDisplay({fixedDp:2})}}}}))).reduce((y,g)=>g.status==="rejected"?y:{...y,...g.value},{})};var ye=async({accountIndex:r,xpub:e,isTestnet:t,walletType:n})=>{switch(n){case vmModuleTypes.WalletType.Mnemonic:case vmModuleTypes.WalletType.Ledger:case vmModuleTypes.WalletType.Keystone:return {[vmModuleTypes.NetworkVMType.BITCOIN]:coreWalletsSdk.getBech32AddressFromXPub(e,r,t?bitcoinjsLib.networks.testnet:bitcoinjsLib.networks.bitcoin)};case vmModuleTypes.WalletType.LedgerLive:case vmModuleTypes.WalletType.Seedless:{let o=Buffer.from(e,"hex");return {[vmModuleTypes.NetworkVMType.BITCOIN]:coreWalletsSdk.getBtcAddressFromPubKey(o,t?bitcoinjsLib.networks.testnet:bitcoinjsLib.networks.bitcoin)}}default:throw rpcErrors.rpcErrors.invalidParams(`Unsupported wallet type: ${n}`)}};var Qe=zod.z.object({from:zod.z.string(),to:zod.z.string(),amount:zod.z.number(),feeRate:zod.z.number()}),fe=r=>Qe.safeParse(r);var ge=r=>{if(!r)return !1;let e="utxos"in r,t="locked"in r,n="unlockedUnstaked"in r;return e&&!n&&!t};var he=(r,e)=>r/e;var Te=async({request:r,network:e,approvalController:t,proxyApiUrl:n})=>{let{dappInfo:o,params:a}=r,{success:s,data:p,error:i}=fe(a);if(!s)return console.error("invalid params",i),{error:rpcErrors.rpcErrors.invalidParams({message:"Transaction params are invalid",data:{cause:i}})};let v=(await N({addresses:[p.from],network:e,proxyApiUrl:n,withScripts:!0}))?.[p.from]?.[e.networkToken.symbol];if(!ge(v))return {error:rpcErrors.rpcErrors.internal("Balance for the source account is not available")};let l=m({isTestnet:!!e.isTestnet,proxyApiUrl:n}),{to:b,from:R,amount:S,feeRate:E}=p,{inputs:y,outputs:g,fee:D}=coreWalletsSdk.createTransferTx(b,R,S,E,v.utxos,l.getNetwork());if(!y||!g)return {error:rpcErrors.rpcErrors.internal("Unable to create transaction")};let F={title:"Approve Transaction",network:{chainId:e.chainId,name:e.chainName,logoUri:e.logoUri},details:[{title:"Transaction Details",items:[K("Website",new URL(o.url).hostname),U("From",R),U("To",b),z("Amount",BigInt(S),e.networkToken.decimals,e.networkToken.symbol)]}],networkFeeSelector:!0},$={type:vmModuleTypes.RpcMethod.BITCOIN_SEND_TRANSACTION,account:R,data:{to:b,amount:S,fee:D,feeRate:E,gasLimit:he(D,E),inputs:y,outputs:g,balance:v}},h=await t.requestApproval({request:r,displayData:F,signingData:$});if("error"in h)return {error:h.error};let T;try{T=await qe(l,h);}catch(O){return {error:rpcErrors.rpcErrors.internal({message:"Unable to get transaction hash",data:{cause:O}})}}return ze({provider:l,txHash:T,onTransactionConfirmed:t.onTransactionConfirmed,onTransactionReverted:t.onTransactionReverted}),{result:T}},qe=async(r,e)=>"txHash"in e?e.txHash:r.issueRawTx(e.signedData),ze=async({provider:r,txHash:e,onTransactionConfirmed:t,onTransactionReverted:n})=>{try{await r.waitForTx(e),t(e);}catch(o){console.error(o),n(e);}};var u,_,Pe=class{constructor({environment:e,approvalController:t}){P(this,u,void 0);P(this,_,void 0);let{proxyApiUrl:n}=te(e);x(this,_,t),x(this,u,n);}getProvider(e){return m({isTestnet:!!e.isTestnet,proxyApiUrl:c(this,u)})}getAddress({accountIndex:e,xpub:t,isTestnet:n,walletType:o}){return ye({accountIndex:e,xpub:t,isTestnet:n,walletType:o})}getBalances({addresses:e,currency:t,network:n,storage:o}){return N({addresses:e,currency:t,network:n,proxyApiUrl:c(this,u),storage:o})}getManifest(){let e=vmModuleTypes.parseManifest(re);return e.success?e.data:void 0}getNetworkFee(e){return ne({isTestnet:!!e.isTestnet,proxyApiUrl:c(this,u)})}async getTransactionHistory({address:e,network:t}){return {transactions:await se({address:e,network:t,proxyApiUrl:c(this,u)})}}getTokens(e){return Promise.resolve([])}async onRpcRequest(e,t){switch(e.method){case vmModuleTypes.RpcMethod.BITCOIN_SEND_TRANSACTION:return Te({request:e,network:t,approvalController:c(this,_),proxyApiUrl:c(this,u)});default:return {error:rpcErrors.rpcErrors.methodNotSupported(`Method ${e.method} not supported`)}}}};u=new WeakMap,_=new WeakMap;
12
+ var xe=Object.defineProperty;var ve=(t,e,r)=>e in t?xe(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var Y=(t,e,r)=>(ve(t,typeof e!="symbol"?e+"":e,r),r),Z=(t,e,r)=>{if(!e.has(t))throw TypeError("Cannot "+r)};var c=(t,e,r)=>(Z(t,e,"read from private field"),r?r.call(t):e.get(t)),k=(t,e,r)=>{if(e.has(t))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(t):e.set(t,r);},P=(t,e,r,n)=>(Z(t,e,"write to private field"),n?n.call(t,r):e.set(t,r),r);var be={glacierApiUrl:"https://glacier-api.avax.network",proxyApiUrl:"https://proxy-api.avax.network"},Re={glacierApiUrl:"https://glacier-api-dev.avax.network",proxyApiUrl:"https://proxy-api-dev.avax.network"},ee=t=>{switch(t){case vmModuleTypes.Environment.PRODUCTION:return be;case vmModuleTypes.Environment.DEV:return Re}};var te={name:"Bitcoin",description:"",version:"0.0.1",sources:{module:{checksum:"",location:{npm:{filePath:"dist/bundle.js",packageName:"@avalabs/bitcoin-module",registry:"https://registry.npmjs.org"}}},provider:{checksum:"",location:{npm:{filePath:"dist/provider.js",packageName:"@avalabs/bitcoin-module",registry:"https://registry.npmjs.org"}}}},network:{chainIds:["bip122:000000000019d6689c085ae165831e93","bip122:000000000933ea01ad0ee984209779ba"],namespaces:["bip122"]},cointype:"0",permissions:{rpc:{dapps:!0,methods:["bitcoin_sendTransaction"]}},manifestVersion:"0.0"};var m=({isTestnet:t,proxyApiUrl:e})=>new coreWalletsSdk.BitcoinProvider(!t,void 0,`${e}/proxy/nownodes/${t?"btcbook-testnet":"btcbook"}`,`${e}/proxy/nownodes/${t?"btc-testnet":"btc"}`,process.env.GLACIER_API_KEY?{token:process.env.GLACIER_API_KEY}:{});async function re({isTestnet:t,proxyApiUrl:e}){let r=m({isTestnet:t,proxyApiUrl:e}),{high:n,low:o,medium:s}=await r.getFeeRates();return {low:{maxFeePerGas:BigInt(o)},medium:{maxFeePerGas:BigInt(s)},high:{maxFeePerGas:BigInt(n)},isFixedFee:!1}}var oe=(t,{address:e,network:r})=>{let{explorerUrl:n,networkToken:o}=r,s=t.addresses[0]??"";return {chainId:r.chainId.toString(),explorerLink:`${n}/tx/${t.hash}`,from:t.isSender?e:s,gasUsed:t.fee.toString(),hash:t.hash,isContractCall:!1,isIncoming:!t.isSender,isOutgoing:t.isSender,isSender:t.isSender,timestamp:t.receivedTime*1e3,to:t.isSender?s:e,tokens:[{amount:(Math.abs(t.amount)/10**o.decimals).toString(),decimal:o.decimals.toString(),name:o.name,symbol:o.symbol,type:vmModuleTypes.TokenType.NATIVE}],txType:t.isSender?vmModuleTypes.TransactionType.SEND:vmModuleTypes.TransactionType.RECEIVE}};var se=async({address:t,network:e,proxyApiUrl:r})=>(await m({isTestnet:!!e.isTestnet,proxyApiUrl:r}).getTxHistory(t)).map(s=>oe(s,{address:t,network:e}));var V=async({operation:t,isSuccess:e,maxRetries:r=10,backoffPolicy:n=S.exponential()})=>{let o=0,s=0,a;for(;s<r;){s>0&&await we(o);try{let i=await t(s);if(e(i))return i}catch(i){a=i;}o=n(s),s++;}let p=a?`Max retry exceeded. ${a}`:"Max retry exceeded.";throw new Error(p)},S=class{static exponential(){return e=>Math.pow(2,e)*1e3}static constant(e){return r=>e*1e3}static constantMs(e){return r=>e}};function we(t){return new Promise(e=>setTimeout(e,t))}var j=t=>V({operation:e=>t(e>0),maxRetries:2,backoffPolicy:S.constant(1),isSuccess:e=>e?.status?.error_code!==429});function ae(t){let e,r=0;for(e=0;e<t.length;e++)r+=t.charCodeAt(e)*(e+1);return r}function q(t){let e,r=0;for(e=0;e<t.length;e++){let n=ae(t[e]??"");r=r+65027/n;}return (""+r).slice(0,16)}var W=t=>new core.Zodios(`${t}/proxy/coingecko`,[{method:"post",path:"/simple/price",parameters:[{name:"ids",type:"Query",schema:zod.string()},{name:"vs_currencies",type:"Query",schema:zod.string()},{name:"include_market_cap",type:"Query",schema:zod.string().optional()},{name:"include_24hr_vol",type:"Query",schema:zod.string().optional()},{name:"include_24hr_change",type:"Query",schema:zod.string().optional()},{name:"include_last_updated_at",type:"Query",schema:zod.string().optional()}],alias:"simplePrice",response:vmModuleTypes.RawSimplePriceResponseSchema},{method:"post",path:"/simple/token_price/:id",parameters:[{name:"id",type:"Path",schema:zod.string()},{name:"contract_addresses",type:"Query",schema:zod.string().array()},{name:"vs_currencies",type:"Query",schema:zod.string().array()},{name:"include_market_cap",type:"Query",schema:zod.boolean().optional()},{name:"include_24hr_vol",type:"Query",schema:zod.boolean().optional()},{name:"include_24hr_change",type:"Query",schema:zod.boolean().optional()}],alias:"simplePriceByContractAddresses",response:vmModuleTypes.SimplePriceResponseSchema}],{axiosConfig:{headers:{"Content-Type":"application/json"}}});var ie=coreCoingeckoSdk.getBasicCoingeckoHttp(),g,x,w=class{constructor({storage:e,proxyApiUrl:r}){k(this,g,void 0);k(this,x,void 0);Y(this,"transformSimplePriceResponse",(e,r=[coreCoingeckoSdk.VsCurrencyType.USD])=>{let n={};return Object.keys(e).forEach(o=>{let s=e[o];n[o]={},r.forEach(a=>{n[o]={[a]:{price:s?.[a],change24:s?.[`${a}_24h_change`],vol24:s?.[`${a}_24h_vol`],marketCap:s?.[`${a}_market_cap`]}};});}),n});P(this,g,e),P(this,x,r);}async getSimplePrice({coinIds:e=[],currencies:r=[coreCoingeckoSdk.VsCurrencyType.USD]}){let n,s=`getSimplePrice-${e?`${q(e)}-${r.toString()}`:`${r.toString()}`}`;if(n=c(this,g)?.get?.(s),n)return n;try{n=await j(a=>this.simplePrice({coinIds:e,currencies:r,marketCap:!0,vol24:!0,change24:!0,useCoingeckoProxy:a}));}catch{n=void 0;}return c(this,g)?.set?.(s,n),n}async getPricesByAddresses(e,r,n=coreCoingeckoSdk.VsCurrencyType.USD){let o,a=`getPricesWithMarketDataByAddresses-${`${q(e)}-${r}-${n}`}`;if(o=c(this,g)?.get?.(a),o)return o;try{o=await j(p=>this.fetchPricesByAddresses({assetPlatformId:r,tokenAddresses:e,currency:n,useCoingeckoProxy:p}));}catch{o=void 0;}return c(this,g)?.set?.(a,o),o}async fetchPricesByAddresses({assetPlatformId:e,tokenAddresses:r,currency:n=coreCoingeckoSdk.VsCurrencyType.USD,useCoingeckoProxy:o=!1}){return o?W(c(this,x)).simplePriceByContractAddresses(void 0,{params:{id:e},queries:{contract_addresses:r,vs_currencies:[n],include_market_cap:!0,include_24hr_vol:!0,include_24hr_change:!0}}):coreCoingeckoSdk.simpleTokenPrice(ie,{assetPlatformId:e,tokenAddresses:r,currencies:[n],marketCap:!0,vol24:!0,change24:!0})}async simplePrice({coinIds:e=[],currencies:r=[coreCoingeckoSdk.VsCurrencyType.USD],marketCap:n=!1,vol24:o=!1,change24:s=!1,lastUpdated:a=!1,useCoingeckoProxy:p=!1,shouldThrow:i=!0}){if(p){let M=await W(c(this,x)).simplePrice(void 0,{queries:{ids:e?.join(","),vs_currencies:r.join(","),include_market_cap:String(n),include_24hr_vol:String(o),include_24hr_change:String(s),include_last_updated_at:String(a)}});return this.transformSimplePriceResponse(M,r)}return coreCoingeckoSdk.simplePrice(ie,{coinIds:e,currencies:r,marketCap:n,vol24:o,change24:s,lastUpdated:a,shouldThrow:i})}};g=new WeakMap,x=new WeakMap;var Fe="https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/usd.min.json",Le="https://latest.currency-api.pages.dev/v1/currencies/usd.min.json",pe=zod.object({date:zod.string(),usd:zod.record(zod.number())});new core.Zodios(Fe,[{method:"get",path:"",alias:"getExchangeRates",response:pe}]);new core.Zodios(Le,[{method:"get",path:"",alias:"getExchangeRates",response:pe}]);var z=(t,e,r,n)=>({label:t,type:vmModuleTypes.DetailItemType.CURRENCY,value:e,maxDecimals:r,symbol:n});var me=(t,e)=>({label:t,value:e,type:vmModuleTypes.DetailItemType.LINK}),N=(t,e)=>({label:t,type:vmModuleTypes.DetailItemType.ADDRESS,value:e});var le=(t,e,r)=>{let n=r?.[t]?.[e??""]??{};return {priceInCurrency:n.price??void 0,marketCap:n.marketCap??void 0,vol24:n.vol24??void 0,change24:n.change24??void 0}};var U=async({addresses:t,currency:e,network:r,withScripts:n,proxyApiUrl:o,storage:s})=>{let a=m({isTestnet:!!r.isTestnet,proxyApiUrl:o}),p=new w({proxyApiUrl:o,storage:s}),i=r.pricingProviders?.coingecko.nativeTokenId,v=typeof e=="string"&&typeof i=="string"?await p.getSimplePrice({coinIds:[i],currencies:[e]}):void 0,{priceInCurrency:l,change24:b,marketCap:R,vol24:I}=le(i??"",e,v);return (await Promise.allSettled(t.map(async y=>{let{balance:f,utxos:D,balanceUnconfirmed:F,utxosUnconfirmed:L}=await a.getUtxoBalance(y,n),h=new coreUtilsSdk.TokenUnit(f,r.networkToken.decimals,r.networkToken.symbol),T=l!==void 0?h.mul(l):void 0,$=h.toDisplay(),O=new coreUtilsSdk.TokenUnit(F,r.networkToken.decimals,r.networkToken.symbol),K=l!==void 0?O.mul(l):void 0,Pe=r.networkToken.symbol;return {[y]:{[Pe]:{...r.networkToken,utxos:D,utxosUnconfirmed:L,coingeckoId:i??"",type:vmModuleTypes.TokenType.NATIVE,balance:h.toSubUnit(),balanceDisplayValue:$,balanceInCurrency:T?.toDisplay({fixedDp:2,asNumber:!0}),balanceCurrencyDisplayValue:T?.toDisplay({fixedDp:2}),priceInCurrency:l,marketCap:R,vol24:I,change24:b,unconfirmedBalance:O.toSubUnit(),unconfirmedBalanceDisplayValue:O.toDisplay(),unconfirmedBalanceInCurrency:K?.toDisplay({fixedDp:2,asNumber:!0}),unconfirmedBalanceCurrencyDisplayValue:K?.toDisplay({fixedDp:2})}}}}))).reduce((y,f)=>f.status==="rejected"?y:{...y,...f.value},{})};var ye=async({accountIndex:t,xpub:e,isTestnet:r,walletType:n})=>{switch(n){case vmModuleTypes.WalletType.Mnemonic:case vmModuleTypes.WalletType.Ledger:case vmModuleTypes.WalletType.Keystone:return {[vmModuleTypes.NetworkVMType.BITCOIN]:coreWalletsSdk.getBech32AddressFromXPub(e,t,r?bitcoinjsLib.networks.testnet:bitcoinjsLib.networks.bitcoin)};case vmModuleTypes.WalletType.LedgerLive:case vmModuleTypes.WalletType.Seedless:{let o=Buffer.from(e,"hex");return {[vmModuleTypes.NetworkVMType.BITCOIN]:coreWalletsSdk.getBtcAddressFromPubKey(o,r?bitcoinjsLib.networks.testnet:bitcoinjsLib.networks.bitcoin)}}default:throw rpcErrors.rpcErrors.invalidParams(`Unsupported wallet type: ${n}`)}};var qe=zod.z.object({from:zod.z.string(),to:zod.z.string(),amount:zod.z.number(),feeRate:zod.z.number()}),ge=t=>qe.safeParse(t);var fe=t=>{if(!t)return !1;let e="utxos"in t,r="locked"in t,n="unlockedUnstaked"in t;return e&&!n&&!r};var he=(t,e)=>t/e;var Te=async({request:t,network:e,approvalController:r,proxyApiUrl:n})=>{let{dappInfo:o,params:s}=t,{success:a,data:p,error:i}=ge(s);if(!a)return console.error("invalid params",i),{error:rpcErrors.rpcErrors.invalidParams({message:"Transaction params are invalid",data:{cause:i}})};let v=(await U({addresses:[p.from],network:e,proxyApiUrl:n,withScripts:!0}))?.[p.from]?.[e.networkToken.symbol];if(!fe(v))return {error:rpcErrors.rpcErrors.internal("Balance for the source account is not available")};let l=m({isTestnet:!!e.isTestnet,proxyApiUrl:n}),{to:b,from:R,amount:I,feeRate:E}=p,{inputs:y,outputs:f,fee:D}=coreWalletsSdk.createTransferTx(b,R,I,E,v.utxos,l.getNetwork());if(!y||!f)return {error:rpcErrors.rpcErrors.internal("Unable to create transaction")};let F={title:"Approve Transaction",network:{chainId:e.chainId,name:e.chainName,logoUri:e.logoUri},details:[{title:"Transaction Details",items:[me("Website",o),N("From",R),N("To",b),z("Amount",BigInt(I),e.networkToken.decimals,e.networkToken.symbol)]}],networkFeeSelector:!0},L={type:vmModuleTypes.RpcMethod.BITCOIN_SEND_TRANSACTION,account:R,data:{to:b,amount:I,fee:D,feeRate:E,gasLimit:he(D,E),inputs:y,outputs:f,balance:v}},h=await r.requestApproval({request:t,displayData:F,signingData:L});if("error"in h)return {error:h.error};let T;try{T=await Xe(l,h);}catch($){return {error:rpcErrors.rpcErrors.internal({message:"Unable to get transaction hash",data:{cause:$}})}}return ze({provider:l,txHash:T,onTransactionConfirmed:r.onTransactionConfirmed,onTransactionReverted:r.onTransactionReverted,requestId:t.requestId}),{result:T}},Xe=async(t,e)=>"txHash"in e?e.txHash:t.issueRawTx(e.signedData),ze=async({provider:t,txHash:e,onTransactionConfirmed:r,onTransactionReverted:n,requestId:o})=>{try{await t.waitForTx(e),r(e,o);}catch(s){console.error(s),n(e,o);}};var u,_,ke=class{constructor({environment:e,approvalController:r}){k(this,u,void 0);k(this,_,void 0);let{proxyApiUrl:n}=ee(e);P(this,_,r),P(this,u,n);}getProvider(e){return m({isTestnet:!!e.isTestnet,proxyApiUrl:c(this,u)})}getAddress({accountIndex:e,xpub:r,isTestnet:n,walletType:o}){return ye({accountIndex:e,xpub:r,isTestnet:n,walletType:o})}getBalances({addresses:e,currency:r,network:n,storage:o}){return U({addresses:e,currency:r,network:n,proxyApiUrl:c(this,u),storage:o})}getManifest(){let e=vmModuleTypes.parseManifest(te);return e.success?e.data:void 0}getNetworkFee(e){return re({isTestnet:!!e.isTestnet,proxyApiUrl:c(this,u)})}async getTransactionHistory({address:e,network:r}){return {transactions:await se({address:e,network:r,proxyApiUrl:c(this,u)})}}getTokens(e){return Promise.resolve([])}async onRpcRequest(e,r){switch(e.method){case vmModuleTypes.RpcMethod.BITCOIN_SEND_TRANSACTION:return Te({request:e,network:r,approvalController:c(this,_),proxyApiUrl:c(this,u)});default:return {error:rpcErrors.rpcErrors.methodNotSupported(`Method ${e.method} not supported`)}}}};u=new WeakMap,_=new WeakMap;
13
13
 
14
- exports.BitcoinModule = Pe;
14
+ exports.BitcoinModule = ke;
15
15
  exports.calculateGasLimit = he;
16
16
  //# sourceMappingURL=out.js.map
17
17
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/module.ts","../src/env.ts","../manifest.json","../src/utils/get-provider.ts","../src/handlers/get-network-fee/get-network-fee.ts","../src/handlers/get-transaction-history/convert-btc-transaction.ts","../src/handlers/get-transaction-history/get-transaction-history.ts","../src/handlers/get-balances/get-balances.ts","../../../packages-internal/utils/src/services/token-service/token-service.ts","../../../packages-internal/utils/src/utils/retry.ts","../../../packages-internal/utils/src/utils/coingecko-retry.ts","../../../packages-internal/utils/src/utils/charsum.ts","../../../packages-internal/utils/src/utils/array-hash.ts","../../../packages-internal/utils/src/services/token-service/coingecko-proxy-client.ts","../../../packages-internal/utils/src/services/pricing-service/exchange-rates.ts","../../../packages-internal/utils/src/utils/detail-item.ts","../src/utils/extract-token-market-data.ts","../src/handlers/get-address/get-address.ts","../src/handlers/bitcoin-send-transaction/bitcoin-send-transaction.ts","../src/handlers/bitcoin-send-transaction/schema.ts","../src/utils/is-btc-balance.ts","../src/utils/calculate-gas-limit.ts"],"names":["RpcMethod","parseManifest","rpcErrors","Environment","prodEnv","devEnv","getEnv","environment","manifest_default","BitcoinProvider","getProvider","isTestnet","proxyApiUrl","getNetworkFee","provider","high","low","medium","TokenType","TransactionType","convertBtcTransaction","tx","address","network","explorerUrl","networkToken","txAddress","getTransactionHistory","TokenUnit","VsCurrencyType","getBasicCoingeckoHttp","simplePrice","simpleTokenPrice","retry","operation","isSuccess","maxRetries","backoffPolicy","RetryBackoffPolicy","backoffPeriodMillis","retries","lastError","delay","result","err","errorMessage","retryIndex","secondsToDelay","_","msToDelay","ms","r","coingeckoRetry","response","charsum","s","i","sum","arrayHash","array","cs","Zodios","RawSimplePriceResponseSchema","SimplePriceResponseSchema","boolean","string","coingeckoProxyClient","coingeckoBasicClient","_storage","_proxyApiUrl","TokenService","storage","__privateAdd","__publicField","data","currencies","formattedData","id","tokenData","currency","__privateSet","coinIds","cacheId","__privateGet","useCoingeckoProxy","tokenAddresses","assetPlatformId","marketCap","vol24","change24","lastUpdated","shouldThrow","rawData","number","object","record","CURRENCY_EXCHANGE_RATES_URL","CURRENCY_EXCHANGE_RATES_FALLBACK_URL","ExchangeRateSchema","exchangeRateApiClient","exchangeRateFallbackApiClient","DetailItemType","currencyItem","label","value","maxDecimals","symbol","textItem","alignment","addressItem","extractTokenMarketData","coinId","coinData","getBalances","addresses","withScripts","tokenService","coingeckoTokenId","marketData","priceInCurrency","balanceInSatoshis","utxos","unconfirmedBalanceInSatoshis","utxosUnconfirmed","balance","balanceInCurrency","balanceDisplayValue","unconfirmedBalance","unconfirmedBalanceInCurrency","acc","accountBalance","getBech32AddressFromXPub","getBtcAddressFromPubKey","networks","NetworkVMType","WalletType","getAddress","accountIndex","xpub","walletType","pubKeyBuffer","z","paramsSchema","parseRequestParams","params","isBtcBalance","hasUtxos","hasLocked","hasUnlockedUnstaked","createTransferTx","calculateGasLimit","fee","feeRate","bitcoinSendTransaction","request","approvalController","dappInfo","rawParams","success","parseError","btcBalance","to","from","amount","inputs","outputs","displayData","signingData","txHash","getTxHash","error","waitForTransactionReceipt","onTransactionConfirmed","onTransactionReverted","_approvalController","BitcoinModule"],"mappings":"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","sourcesContent":["import type {\n Module,\n Manifest,\n NetworkFees,\n GetTransactionHistory,\n RpcRequest,\n Network,\n Environment,\n GetBalancesParams,\n GetAddressParams,\n GetAddressResponse,\n ApprovalController,\n} from '@avalabs/vm-module-types';\nimport { RpcMethod, parseManifest } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { getEnv } from './env';\n\nimport ManifestJson from '../manifest.json';\nimport { getNetworkFee } from './handlers/get-network-fee/get-network-fee';\nimport { getTransactionHistory } from './handlers/get-transaction-history/get-transaction-history';\nimport { getBalances } from './handlers/get-balances/get-balances';\nimport { getAddress } from './handlers/get-address/get-address';\nimport { bitcoinSendTransaction } from './handlers/bitcoin-send-transaction/bitcoin-send-transaction';\nimport type { BitcoinProvider } from '@avalabs/core-wallets-sdk';\nimport { getProvider } from './utils/get-provider';\n\nexport class BitcoinModule implements Module {\n #proxyApiUrl: string;\n #approvalController: ApprovalController;\n\n constructor({\n environment,\n approvalController,\n }: {\n environment: Environment;\n approvalController: ApprovalController;\n }) {\n const { proxyApiUrl } = getEnv(environment);\n\n this.#approvalController = approvalController;\n this.#proxyApiUrl = proxyApiUrl;\n }\n\n getProvider(network: Network): BitcoinProvider {\n return getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl: this.#proxyApiUrl,\n });\n }\n\n getAddress({ accountIndex, xpub, isTestnet, walletType }: GetAddressParams): Promise<GetAddressResponse> {\n return getAddress({ accountIndex, xpub, isTestnet, walletType });\n }\n\n getBalances({ addresses, currency, network, storage }: GetBalancesParams) {\n return getBalances({\n addresses,\n currency,\n network,\n proxyApiUrl: this.#proxyApiUrl,\n storage,\n });\n }\n\n getManifest(): Manifest | undefined {\n const result = parseManifest(ManifestJson);\n return result.success ? result.data : undefined;\n }\n\n getNetworkFee(network: Network): Promise<NetworkFees> {\n return getNetworkFee({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl: this.#proxyApiUrl,\n });\n }\n\n async getTransactionHistory({ address, network }: GetTransactionHistory) {\n return {\n transactions: await getTransactionHistory({\n address,\n network,\n proxyApiUrl: this.#proxyApiUrl,\n }),\n };\n }\n\n getTokens(_: Network) {\n return Promise.resolve([]);\n }\n\n async onRpcRequest(request: RpcRequest, network: Network) {\n switch (request.method) {\n case RpcMethod.BITCOIN_SEND_TRANSACTION:\n return bitcoinSendTransaction({\n request,\n network,\n approvalController: this.#approvalController,\n proxyApiUrl: this.#proxyApiUrl,\n });\n default:\n return { error: rpcErrors.methodNotSupported(`Method ${request.method} not supported`) };\n }\n }\n}\n","import { Environment } from '@avalabs/vm-module-types';\n\ntype Env = {\n glacierApiUrl: string;\n proxyApiUrl: string;\n};\n\nexport const prodEnv: Env = {\n glacierApiUrl: 'https://glacier-api.avax.network',\n proxyApiUrl: 'https://proxy-api.avax.network',\n};\n\nexport const devEnv: Env = {\n glacierApiUrl: 'https://glacier-api-dev.avax.network',\n proxyApiUrl: 'https://proxy-api-dev.avax.network',\n};\n\nexport const getEnv = (environment: Environment): Env => {\n switch (environment) {\n case Environment.PRODUCTION:\n return prodEnv;\n case Environment.DEV:\n return devEnv;\n }\n};\n","{\n \"name\": \"Bitcoin\",\n \"description\": \"\",\n \"version\": \"0.0.1\",\n \"sources\": {\n \"module\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/bundle.js\",\n \"packageName\": \"@avalabs/bitcoin-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n },\n \"provider\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/provider.js\",\n \"packageName\": \"@avalabs/bitcoin-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n }\n },\n \"network\": {\n \"chainIds\": [\"bip122:000000000019d6689c085ae165831e93\", \"bip122:000000000933ea01ad0ee984209779ba\"],\n \"namespaces\": [\"bip122\"]\n },\n \"cointype\": \"0\",\n \"permissions\": {\n \"rpc\": {\n \"dapps\": true,\n \"methods\": [\"bitcoin_sendTransaction\"]\n }\n },\n \"manifestVersion\": \"0.0\"\n}\n","import { BitcoinProvider } from '@avalabs/core-wallets-sdk';\n\ntype ProviderParams = {\n isTestnet: boolean;\n proxyApiUrl: string;\n};\n\nexport const getProvider = ({ isTestnet, proxyApiUrl }: ProviderParams): BitcoinProvider =>\n new BitcoinProvider(\n !isTestnet,\n undefined,\n `${proxyApiUrl}/proxy/nownodes/${isTestnet ? 'btcbook-testnet' : 'btcbook'}`,\n `${proxyApiUrl}/proxy/nownodes/${isTestnet ? 'btc-testnet' : 'btc'}`,\n\n // The Glacier API key is only needed in development to bypass rate limits.\n // It should never be used in production.\n process.env.GLACIER_API_KEY ? { token: process.env.GLACIER_API_KEY } : {},\n );\n","import type { NetworkFees } from '@avalabs/vm-module-types';\n\nimport { getProvider } from '../../utils/get-provider';\n\n/**\n * Returns {@link NetworkFees} based on `estimatesmartfee` RPC call\n */\nexport async function getNetworkFee({\n isTestnet,\n proxyApiUrl,\n}: {\n isTestnet: boolean;\n proxyApiUrl: string;\n}): Promise<NetworkFees> {\n const provider = getProvider({\n isTestnet,\n proxyApiUrl,\n });\n\n const { high, low, medium } = await provider.getFeeRates();\n\n return {\n low: {\n maxFeePerGas: BigInt(low),\n },\n medium: {\n maxFeePerGas: BigInt(medium),\n },\n high: {\n maxFeePerGas: BigInt(high),\n },\n isFixedFee: false,\n };\n}\n","import { TokenType, TransactionType, type Network, type Transaction } from '@avalabs/vm-module-types';\nimport type { BitcoinHistoryTx } from '@avalabs/core-wallets-sdk';\n\ntype ConverterOptions = {\n address: string;\n network: Network;\n};\n\nexport const convertBtcTransaction = (tx: BitcoinHistoryTx, { address, network }: ConverterOptions): Transaction => {\n const { explorerUrl, networkToken } = network;\n const txAddress = tx.addresses[0] ?? '';\n\n return {\n chainId: network.chainId.toString(),\n explorerLink: `${explorerUrl}/tx/${tx.hash}`,\n from: tx.isSender ? address : txAddress,\n gasUsed: tx.fee.toString(),\n hash: tx.hash,\n isContractCall: false,\n isIncoming: !tx.isSender,\n isOutgoing: tx.isSender,\n isSender: tx.isSender,\n timestamp: tx.receivedTime * 1000,\n to: tx.isSender ? txAddress : address,\n tokens: [\n {\n amount: (Math.abs(tx.amount) / 10 ** networkToken.decimals).toString(),\n decimal: networkToken.decimals.toString(),\n name: networkToken.name,\n symbol: networkToken.symbol,\n type: TokenType.NATIVE,\n },\n ],\n txType: tx.isSender ? TransactionType.SEND : TransactionType.RECEIVE,\n };\n};\n","import type { Network } from '@avalabs/vm-module-types';\n\nimport { getProvider } from '../../utils/get-provider';\n\nimport { convertBtcTransaction } from './convert-btc-transaction';\n\ntype GetBtcTransactionHistoryOptions = {\n network: Network;\n address: string;\n proxyApiUrl: string;\n};\n\nexport const getTransactionHistory = async ({ address, network, proxyApiUrl }: GetBtcTransactionHistoryOptions) => {\n const provider = getProvider({ isTestnet: Boolean(network.isTestnet), proxyApiUrl });\n const rawHistory = await provider.getTxHistory(address);\n\n return rawHistory.map((tx) =>\n convertBtcTransaction(tx, {\n address,\n network,\n }),\n );\n};\n","import { type GetBalancesParams, TokenType, type TokenWithBalanceBTC } from '@avalabs/vm-module-types';\nimport { TokenUnit } from '@avalabs/core-utils-sdk';\nimport type { VsCurrencyType } from '@avalabs/core-coingecko-sdk';\n\nimport { TokenService } from '@internal/utils';\n\nimport { getProvider } from '../../utils/get-provider';\nimport { extractTokenMarketData } from '../../utils/extract-token-market-data';\n\ntype GetBtcBalancesResponse = Record<string, Record<string, TokenWithBalanceBTC>>;\n\ntype GetBTCBalancesParams = Omit<GetBalancesParams, 'currency'> & {\n proxyApiUrl: string;\n withScripts?: boolean;\n currency?: string;\n};\n\nexport const getBalances = async ({\n addresses,\n currency,\n network,\n withScripts,\n proxyApiUrl,\n storage,\n}: GetBTCBalancesParams): Promise<GetBtcBalancesResponse> => {\n const provider = getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl,\n });\n\n const tokenService = new TokenService({ proxyApiUrl, storage });\n const coingeckoTokenId = network.pricingProviders?.coingecko.nativeTokenId;\n const withPrices = typeof currency === 'string' && typeof coingeckoTokenId === 'string';\n const marketData = withPrices\n ? await tokenService.getSimplePrice({\n coinIds: [coingeckoTokenId],\n currencies: [currency] as VsCurrencyType[],\n })\n : undefined;\n const { priceInCurrency, change24, marketCap, vol24 } = extractTokenMarketData(\n coingeckoTokenId ?? '',\n currency,\n marketData,\n );\n\n const balances = await Promise.allSettled(\n addresses.map(async (address) => {\n const {\n balance: balanceInSatoshis,\n utxos,\n balanceUnconfirmed: unconfirmedBalanceInSatoshis,\n utxosUnconfirmed,\n } = await provider.getUtxoBalance(address, withScripts);\n\n const balance = new TokenUnit(balanceInSatoshis, network.networkToken.decimals, network.networkToken.symbol);\n const balanceInCurrency = priceInCurrency !== undefined ? balance.mul(priceInCurrency) : undefined;\n const balanceDisplayValue = balance.toDisplay();\n\n const unconfirmedBalance = new TokenUnit(\n unconfirmedBalanceInSatoshis,\n network.networkToken.decimals,\n network.networkToken.symbol,\n );\n const unconfirmedBalanceInCurrency =\n priceInCurrency !== undefined ? unconfirmedBalance.mul(priceInCurrency) : undefined;\n\n const symbol = network.networkToken.symbol;\n\n return {\n [address]: {\n [symbol]: {\n ...network.networkToken,\n utxos,\n utxosUnconfirmed,\n coingeckoId: coingeckoTokenId ?? '',\n type: TokenType.NATIVE,\n balance: balance.toSubUnit(),\n balanceDisplayValue,\n balanceInCurrency: balanceInCurrency?.toDisplay({ fixedDp: 2, asNumber: true }),\n balanceCurrencyDisplayValue: balanceInCurrency?.toDisplay({ fixedDp: 2 }),\n priceInCurrency,\n marketCap,\n vol24,\n change24,\n unconfirmedBalance: unconfirmedBalance.toSubUnit(),\n unconfirmedBalanceDisplayValue: unconfirmedBalance.toDisplay(),\n unconfirmedBalanceInCurrency: unconfirmedBalanceInCurrency?.toDisplay({\n fixedDp: 2,\n asNumber: true,\n }),\n unconfirmedBalanceCurrencyDisplayValue: unconfirmedBalanceInCurrency?.toDisplay({ fixedDp: 2 }),\n },\n },\n };\n }),\n );\n\n return balances.reduce((acc, accountBalance) => {\n if (accountBalance.status === 'rejected') {\n return acc;\n }\n\n return {\n ...acc,\n ...accountBalance.value,\n };\n }, {});\n};\n","import {\n VsCurrencyType,\n getBasicCoingeckoHttp,\n simplePrice,\n simpleTokenPrice,\n type SimplePriceParams,\n} from '@avalabs/core-coingecko-sdk';\nimport type { Storage, RawSimplePriceResponse, SimplePriceResponse } from '@avalabs/vm-module-types';\nimport { coingeckoRetry } from '../../utils/coingecko-retry';\nimport { arrayHash } from '../../utils/array-hash';\nimport { coingeckoProxyClient } from './coingecko-proxy-client';\n\nconst coingeckoBasicClient = getBasicCoingeckoHttp();\n\nexport class TokenService {\n #storage?: Storage;\n #proxyApiUrl: string;\n\n constructor({ storage, proxyApiUrl }: { proxyApiUrl: string; storage?: Storage }) {\n this.#storage = storage;\n this.#proxyApiUrl = proxyApiUrl;\n }\n\n /**\n * Get token price with market data first on coingecko (free tier) directly,\n * if we get 429 error, retry it on coingecko proxy (paid service)\n * @returns token price with market data\n */\n async getSimplePrice({\n coinIds = [],\n currencies = [VsCurrencyType.USD],\n }: SimplePriceParams): Promise<SimplePriceResponse | undefined> {\n let data: SimplePriceResponse | undefined;\n\n const key = coinIds ? `${arrayHash(coinIds)}-${currencies.toString()}` : `${currencies.toString()}`;\n\n const cacheId = `getSimplePrice-${key}`;\n\n data = this.#storage?.get?.<SimplePriceResponse>(cacheId);\n\n if (data) return data;\n\n try {\n data = await coingeckoRetry((useCoingeckoProxy) =>\n this.simplePrice({\n coinIds,\n currencies,\n marketCap: true,\n vol24: true,\n change24: true,\n useCoingeckoProxy,\n }),\n );\n } catch {\n data = undefined;\n }\n this.#storage?.set?.(cacheId, data);\n return data;\n }\n\n /**\n * Get token price with market data for a list of addresses\n * @param tokenAddresses the token addresses\n * @param assetPlatformId The platform id for all the tokens in the list\n * @param currency the currency to be used\n * @returns a list of token price with market data\n */\n async getPricesByAddresses(\n tokenAddresses: string[],\n assetPlatformId: string,\n currency: VsCurrencyType = VsCurrencyType.USD,\n ): Promise<SimplePriceResponse | undefined> {\n let data: SimplePriceResponse | undefined;\n\n const key = `${arrayHash(tokenAddresses)}-${assetPlatformId}-${currency}`;\n\n const cacheId = `getPricesWithMarketDataByAddresses-${key}`;\n data = this.#storage?.get?.<SimplePriceResponse>(cacheId);\n\n if (data) return data;\n\n try {\n data = await coingeckoRetry((useCoingeckoProxy) =>\n this.fetchPricesByAddresses({\n assetPlatformId,\n tokenAddresses,\n currency,\n useCoingeckoProxy,\n }),\n );\n } catch {\n data = undefined;\n }\n this.#storage?.set?.(cacheId, data);\n return data;\n }\n\n private async fetchPricesByAddresses({\n assetPlatformId,\n tokenAddresses,\n currency = VsCurrencyType.USD,\n useCoingeckoProxy = false,\n }: {\n assetPlatformId: string;\n tokenAddresses: string[];\n currency: VsCurrencyType;\n useCoingeckoProxy?: boolean;\n }): Promise<SimplePriceResponse> {\n if (useCoingeckoProxy) {\n return coingeckoProxyClient(this.#proxyApiUrl).simplePriceByContractAddresses(undefined, {\n params: {\n id: assetPlatformId,\n },\n queries: {\n contract_addresses: tokenAddresses,\n vs_currencies: [currency],\n include_market_cap: true,\n include_24hr_vol: true,\n include_24hr_change: true,\n },\n });\n }\n\n return simpleTokenPrice(coingeckoBasicClient, {\n assetPlatformId,\n tokenAddresses,\n currencies: [currency],\n marketCap: true,\n vol24: true,\n change24: true,\n });\n }\n\n private async simplePrice({\n coinIds = [],\n currencies = [VsCurrencyType.USD],\n marketCap = false,\n vol24 = false,\n change24 = false,\n lastUpdated = false,\n useCoingeckoProxy = false,\n shouldThrow = true,\n }: SimplePriceParams & { useCoingeckoProxy?: boolean }): Promise<SimplePriceResponse> {\n if (useCoingeckoProxy) {\n const rawData = await coingeckoProxyClient(this.#proxyApiUrl).simplePrice(undefined, {\n queries: {\n ids: coinIds?.join(','),\n vs_currencies: currencies.join(','),\n include_market_cap: String(marketCap),\n include_24hr_vol: String(vol24),\n include_24hr_change: String(change24),\n include_last_updated_at: String(lastUpdated),\n },\n });\n return this.transformSimplePriceResponse(rawData, currencies);\n }\n return simplePrice(coingeckoBasicClient, {\n coinIds,\n currencies,\n marketCap,\n vol24,\n change24,\n lastUpdated,\n shouldThrow,\n });\n }\n\n private transformSimplePriceResponse = (\n data: RawSimplePriceResponse,\n currencies = [VsCurrencyType.USD],\n ): SimplePriceResponse => {\n const formattedData: SimplePriceResponse = {};\n Object.keys(data).forEach((id) => {\n const tokenData = data[id];\n formattedData[id] = {};\n currencies.forEach((currency: VsCurrencyType) => {\n formattedData[id] = {\n [currency]: {\n price: tokenData?.[currency],\n change24: tokenData?.[`${currency}_24h_change`],\n vol24: tokenData?.[`${currency}_24h_vol`],\n marketCap: tokenData?.[`${currency}_market_cap`],\n },\n };\n });\n });\n return formattedData;\n };\n}\n","const DEFAULT_MAX_RETRIES = 10;\n\ntype RetryParams<T> = {\n operation: (retryIndex: number) => Promise<T>;\n isSuccess: (result: T) => boolean;\n maxRetries?: number;\n backoffPolicy?: RetryBackoffPolicyInterface;\n};\n/*\n * Retries an operation with defined backoff policy.\n *\n * @param operation - The operation to retry.\n * @param isSuccess - The predicate to check if the operation succeeded.\n * @param maxRetries - The maximum number of retries.\n * @param backoffPolicy - Function to generate delay time based on current retry count.\n *\n * @returns The result of the operation.\n * @throws An error if the operation fails after the maximum number of retries.\n *\n * @example\n * const result = await retry(\n * async () => {\n * const response = await fetch('https://example.com')\n * return response.json()\n * },\n * result => result.status === 200\n * )\n */\nexport const retry = async <T>({\n operation,\n isSuccess,\n maxRetries = DEFAULT_MAX_RETRIES,\n backoffPolicy = RetryBackoffPolicy.exponential(),\n}: RetryParams<T>): Promise<T> => {\n let backoffPeriodMillis = 0;\n let retries = 0;\n let lastError: unknown;\n\n while (retries < maxRetries) {\n if (retries > 0) {\n await delay(backoffPeriodMillis);\n }\n\n try {\n const result = await operation(retries);\n\n if (isSuccess(result)) {\n return result;\n }\n } catch (err) {\n // when the operation throws an error, we still retry\n lastError = err;\n }\n\n backoffPeriodMillis = backoffPolicy(retries);\n retries++;\n }\n\n const errorMessage = lastError ? `Max retry exceeded. ${lastError}` : 'Max retry exceeded.';\n\n throw new Error(errorMessage);\n};\n\ntype RetryBackoffPolicyInterface = (retryIndex: number) => number;\n\nexport class RetryBackoffPolicy {\n static exponential(): RetryBackoffPolicyInterface {\n return (retryIndex: number): number => {\n return Math.pow(2, retryIndex) * 1000;\n };\n }\n\n static constant(secondsToDelay: number): RetryBackoffPolicyInterface {\n return (_: number): number => {\n return secondsToDelay * 1000;\n };\n }\n\n static constantMs(msToDelay: number): RetryBackoffPolicyInterface {\n return (_: number): number => {\n return msToDelay;\n };\n }\n}\n\nfunction delay(ms: number) {\n return new Promise((r) => setTimeout(r, ms));\n}\n","import { RetryBackoffPolicy, retry } from './retry';\n\ntype Error = {\n status: {\n error_code: number;\n error_message: string;\n };\n};\n\nexport const coingeckoRetry = <T>(\n operation: (useCoingeckoProxy: boolean) => Promise<T | Error>,\n): Promise<T | undefined> => {\n return retry({\n operation: (retryIndex: number) => operation(retryIndex > 0),\n maxRetries: 2,\n backoffPolicy: RetryBackoffPolicy.constant(1),\n isSuccess: (response: T | Error) => {\n const errorStatus = (response as Error)?.status;\n return errorStatus?.error_code !== 429;\n },\n }) as Promise<T | undefined>;\n};\n","export function charsum(s: string): number {\n let i,\n sum = 0;\n for (i = 0; i < s.length; i++) {\n sum += s.charCodeAt(i) * (i + 1);\n }\n return sum;\n}\n","import { charsum } from './charsum';\n\n// from https://stackoverflow.com/a/25105589\nexport function arrayHash(array: string[]): string {\n let i,\n sum = 0;\n for (i = 0; i < array.length; i++) {\n const cs = charsum(array[i] ?? '');\n sum = sum + 65027 / cs;\n }\n return ('' + sum).slice(0, 16);\n}\n","import { Zodios } from '@zodios/core';\nimport { RawSimplePriceResponseSchema, SimplePriceResponseSchema } from '@avalabs/vm-module-types';\nimport { boolean, string } from 'zod';\n\nexport const coingeckoProxyClient = (proxyApiUrl: string) =>\n new Zodios(\n `${proxyApiUrl}/proxy/coingecko`,\n [\n {\n method: 'post',\n path: '/simple/price',\n parameters: [\n { name: 'ids', type: 'Query', schema: string() },\n { name: 'vs_currencies', type: 'Query', schema: string() },\n {\n name: 'include_market_cap',\n type: 'Query',\n schema: string().optional(),\n },\n {\n name: 'include_24hr_vol',\n type: 'Query',\n schema: string().optional(),\n },\n {\n name: 'include_24hr_change',\n type: 'Query',\n schema: string().optional(),\n },\n {\n name: 'include_last_updated_at',\n type: 'Query',\n schema: string().optional(),\n },\n ],\n alias: 'simplePrice',\n response: RawSimplePriceResponseSchema,\n },\n {\n method: 'post',\n path: '/simple/token_price/:id',\n parameters: [\n { name: 'id', type: 'Path', schema: string() },\n { name: 'contract_addresses', type: 'Query', schema: string().array() },\n { name: 'vs_currencies', type: 'Query', schema: string().array() },\n {\n name: 'include_market_cap',\n type: 'Query',\n schema: boolean().optional(),\n },\n {\n name: 'include_24hr_vol',\n type: 'Query',\n schema: boolean().optional(),\n },\n {\n name: 'include_24hr_change',\n type: 'Query',\n schema: boolean().optional(),\n },\n ],\n alias: 'simplePriceByContractAddresses',\n response: SimplePriceResponseSchema,\n },\n ],\n {\n axiosConfig: {\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n },\n );\n","import { Zodios } from '@zodios/core';\nimport z, { number, object, record, string } from 'zod';\n\nconst CURRENCY_EXCHANGE_RATES_URL =\n 'https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/usd.min.json';\n\nconst CURRENCY_EXCHANGE_RATES_FALLBACK_URL = 'https://latest.currency-api.pages.dev/v1/currencies/usd.min.json';\n\nconst ExchangeRateSchema = object({\n date: string(),\n usd: record(number()),\n});\n\ntype ExchangeRate = z.infer<typeof ExchangeRateSchema>;\n\nconst exchangeRateApiClient = new Zodios(CURRENCY_EXCHANGE_RATES_URL, [\n {\n method: 'get',\n path: '',\n alias: 'getExchangeRates',\n response: ExchangeRateSchema,\n },\n]);\n\nconst exchangeRateFallbackApiClient = new Zodios(CURRENCY_EXCHANGE_RATES_FALLBACK_URL, [\n {\n method: 'get',\n path: '',\n alias: 'getExchangeRates',\n response: ExchangeRateSchema,\n },\n]);\n\nexport const getExchangeRates = async (): Promise<ExchangeRate> => {\n try {\n return await exchangeRateApiClient.getExchangeRates();\n } catch {\n return await exchangeRateFallbackApiClient.getExchangeRates();\n }\n};\n","import {\n type AddressItem,\n type CurrencyItem,\n type NodeIDItem,\n type TextItem,\n type DataItem,\n type DateItem,\n DetailItemType,\n} from '@avalabs/vm-module-types';\n\nexport const currencyItem = (label: string, value: bigint, maxDecimals: number, symbol: string): CurrencyItem => ({\n label,\n type: DetailItemType.CURRENCY,\n value,\n maxDecimals,\n symbol,\n});\n\nexport const textItem = (\n label: string,\n value: string,\n alignment: 'horizontal' | 'vertical' = 'horizontal',\n): TextItem => ({\n label,\n alignment,\n type: DetailItemType.TEXT,\n value,\n});\n\nexport const addressItem = (label: string, value: string): AddressItem => ({\n label,\n type: DetailItemType.ADDRESS,\n value,\n});\n\nexport const nodeIDItem = (label: string, value: string): NodeIDItem => ({\n label,\n type: DetailItemType.NODE_ID,\n value,\n});\n\nexport const dataItem = (label: string, value: string): DataItem => ({\n label,\n type: DetailItemType.DATA,\n value,\n});\n\nexport const dateItem = (label: string, value: string): DateItem => ({\n label,\n type: DetailItemType.DATE,\n value,\n});\n","import type { SimplePriceResponse, TokenMarketData } from '@avalabs/vm-module-types';\n\nexport const extractTokenMarketData = (\n coinId: string,\n currency?: string,\n data?: SimplePriceResponse,\n): TokenMarketData => {\n const coinData = data?.[coinId]?.[currency ?? ''] ?? {};\n\n return {\n priceInCurrency: coinData.price ?? undefined,\n marketCap: coinData.marketCap ?? undefined,\n vol24: coinData.vol24 ?? undefined,\n change24: coinData.change24 ?? undefined,\n };\n};\n","import type { GetAddressParams, GetAddressResponse } from '@avalabs/vm-module-types';\nimport { getBech32AddressFromXPub, getBtcAddressFromPubKey } from '@avalabs/core-wallets-sdk';\nimport { networks } from 'bitcoinjs-lib';\nimport { NetworkVMType, WalletType } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\n\ntype GetAddress = Omit<GetAddressParams, 'xpubXP'>;\n\nexport const getAddress = async ({\n accountIndex,\n xpub,\n isTestnet,\n walletType,\n}: GetAddress): Promise<GetAddressResponse> => {\n switch (walletType) {\n case WalletType.Mnemonic:\n case WalletType.Ledger:\n case WalletType.Keystone: {\n return {\n [NetworkVMType.BITCOIN]: getBech32AddressFromXPub(\n xpub,\n accountIndex,\n isTestnet ? networks.testnet : networks.bitcoin,\n ),\n };\n }\n case WalletType.LedgerLive:\n case WalletType.Seedless: {\n const pubKeyBuffer = Buffer.from(xpub, 'hex');\n return {\n [NetworkVMType.BITCOIN]: getBtcAddressFromPubKey(pubKeyBuffer, isTestnet ? networks.testnet : networks.bitcoin),\n };\n }\n default:\n throw rpcErrors.invalidParams(`Unsupported wallet type: ${walletType}`);\n }\n};\n","import {\n RpcMethod,\n type ApprovalController,\n type DisplayData,\n type Hex,\n type Network,\n type RpcRequest,\n type SigningData,\n type SigningResult,\n} from '@avalabs/vm-module-types';\nimport { parseRequestParams } from './schema';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { getProvider } from '../../utils/get-provider';\nimport { getBalances } from '../get-balances/get-balances';\nimport { isBtcBalance } from '../../utils/is-btc-balance';\nimport { BitcoinProvider, createTransferTx, type BitcoinInputUTXO } from '@avalabs/core-wallets-sdk';\nimport { calculateGasLimit } from '../../utils/calculate-gas-limit';\nimport { addressItem, currencyItem, textItem } from '@internal/utils';\n\ntype BitcoinSendTransactionParams = {\n request: RpcRequest;\n network: Network;\n approvalController: ApprovalController;\n proxyApiUrl: string;\n};\n\nexport const bitcoinSendTransaction = async ({\n request,\n network,\n approvalController,\n proxyApiUrl,\n}: BitcoinSendTransactionParams) => {\n const { dappInfo, params: rawParams } = request;\n\n const { success, data: params, error: parseError } = parseRequestParams(rawParams);\n\n if (!success) {\n console.error('invalid params', parseError);\n return {\n error: rpcErrors.invalidParams({ message: 'Transaction params are invalid', data: { cause: parseError } }),\n };\n }\n\n const balances = await getBalances({ addresses: [params.from], network, proxyApiUrl, withScripts: true });\n const btcBalance = balances?.[params.from]?.[network.networkToken.symbol];\n\n if (!isBtcBalance(btcBalance)) {\n return {\n error: rpcErrors.internal('Balance for the source account is not available'),\n };\n }\n\n const provider = getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl,\n });\n\n const { to, from, amount, feeRate } = params;\n\n const { inputs, outputs, fee } = createTransferTx(\n to,\n from,\n amount,\n feeRate,\n btcBalance.utxos as BitcoinInputUTXO[], // we asked for scripts in getBalances() call\n provider.getNetwork(),\n );\n\n if (!inputs || !outputs) {\n return {\n error: rpcErrors.internal('Unable to create transaction'),\n };\n }\n\n const displayData: DisplayData = {\n title: 'Approve Transaction',\n network: {\n chainId: network.chainId,\n name: network.chainName,\n logoUri: network.logoUri,\n },\n details: [\n {\n title: 'Transaction Details',\n items: [\n textItem('Website', new URL(dappInfo.url).hostname),\n addressItem('From', from),\n addressItem('To', to),\n currencyItem('Amount', BigInt(amount), network.networkToken.decimals, network.networkToken.symbol),\n ],\n },\n ],\n networkFeeSelector: true,\n };\n\n const signingData: SigningData = {\n type: RpcMethod.BITCOIN_SEND_TRANSACTION,\n account: from,\n data: {\n to,\n amount,\n fee,\n feeRate,\n gasLimit: calculateGasLimit(fee, feeRate),\n inputs,\n outputs,\n balance: btcBalance,\n },\n };\n\n const response = await approvalController.requestApproval({ request, displayData, signingData });\n\n if ('error' in response) {\n return {\n error: response.error,\n };\n }\n\n let txHash;\n\n try {\n txHash = await getTxHash(provider, response);\n } catch (error) {\n return {\n error: rpcErrors.internal({ message: 'Unable to get transaction hash', data: { cause: error } }),\n };\n }\n\n waitForTransactionReceipt({\n provider,\n txHash: txHash as Hex,\n onTransactionConfirmed: approvalController.onTransactionConfirmed,\n onTransactionReverted: approvalController.onTransactionReverted,\n });\n\n return {\n result: txHash,\n };\n};\n\nconst getTxHash = async (provider: BitcoinProvider, response: SigningResult) => {\n if ('txHash' in response) {\n return response.txHash;\n }\n\n return provider.issueRawTx(response.signedData);\n};\n\nconst waitForTransactionReceipt = async ({\n provider,\n txHash,\n onTransactionConfirmed,\n onTransactionReverted,\n}: {\n provider: BitcoinProvider;\n txHash: Hex;\n onTransactionConfirmed: (txHash: Hex) => void;\n onTransactionReverted: (txHash: Hex) => void;\n}) => {\n try {\n await provider.waitForTx(txHash);\n onTransactionConfirmed(txHash);\n } catch (err) {\n console.error(err);\n onTransactionReverted(txHash);\n }\n};\n","import { z } from 'zod';\n\nconst paramsSchema = z.object({\n from: z.string(),\n to: z.string(),\n amount: z.number(),\n feeRate: z.number(),\n});\n\nexport const parseRequestParams = (params: unknown) => {\n return paramsSchema.safeParse(params);\n};\n\nexport type BitcoinSendTransactionParams = z.infer<typeof paramsSchema>;\n","import type { TokenWithBalance, TokenWithBalanceBTC } from '@avalabs/vm-module-types';\n\nexport const isBtcBalance = (balance?: TokenWithBalance): balance is TokenWithBalanceBTC => {\n if (!balance) {\n return false;\n }\n\n const hasUtxos = 'utxos' in balance; // BTC, P-Chain or X-Chain\n const hasLocked = 'locked' in balance; // X-Chain only\n const hasUnlockedUnstaked = 'unlockedUnstaked' in balance; // P-Chain only\n\n return hasUtxos && !hasUnlockedUnstaked && !hasLocked;\n};\n","// The transaction's byte size is for BTC as gasLimit is for EVM.\n// Bitcoin's formula for fee is `transactionByteLength * feeRate`.\n// Since we know the `fee` and the `feeRate`, we can get the transaction's\n// byte length by division.\nexport const calculateGasLimit = (fee: number, feeRate: number): number => {\n return fee / feeRate;\n};\n"]}
1
+ {"version":3,"sources":["../src/module.ts","../src/env.ts","../manifest.json","../src/utils/get-provider.ts","../src/handlers/get-network-fee/get-network-fee.ts","../src/handlers/get-transaction-history/convert-btc-transaction.ts","../src/handlers/get-transaction-history/get-transaction-history.ts","../src/handlers/get-balances/get-balances.ts","../../../packages-internal/utils/src/services/token-service/token-service.ts","../../../packages-internal/utils/src/utils/retry.ts","../../../packages-internal/utils/src/utils/coingecko-retry.ts","../../../packages-internal/utils/src/utils/charsum.ts","../../../packages-internal/utils/src/utils/array-hash.ts","../../../packages-internal/utils/src/services/token-service/coingecko-proxy-client.ts","../../../packages-internal/utils/src/services/pricing-service/exchange-rates.ts","../../../packages-internal/utils/src/utils/detail-item.ts","../src/utils/extract-token-market-data.ts","../src/handlers/get-address/get-address.ts","../src/handlers/bitcoin-send-transaction/bitcoin-send-transaction.ts","../src/handlers/bitcoin-send-transaction/schema.ts","../src/utils/is-btc-balance.ts","../src/utils/calculate-gas-limit.ts"],"names":["RpcMethod","parseManifest","rpcErrors","Environment","prodEnv","devEnv","getEnv","environment","manifest_default","BitcoinProvider","getProvider","isTestnet","proxyApiUrl","getNetworkFee","provider","high","low","medium","TokenType","TransactionType","convertBtcTransaction","tx","address","network","explorerUrl","networkToken","txAddress","getTransactionHistory","TokenUnit","VsCurrencyType","getBasicCoingeckoHttp","simplePrice","simpleTokenPrice","retry","operation","isSuccess","maxRetries","backoffPolicy","RetryBackoffPolicy","backoffPeriodMillis","retries","lastError","delay","result","err","errorMessage","retryIndex","secondsToDelay","_","msToDelay","ms","r","coingeckoRetry","response","charsum","s","i","sum","arrayHash","array","cs","Zodios","RawSimplePriceResponseSchema","SimplePriceResponseSchema","boolean","string","coingeckoProxyClient","coingeckoBasicClient","_storage","_proxyApiUrl","TokenService","storage","__privateAdd","__publicField","data","currencies","formattedData","id","tokenData","currency","__privateSet","coinIds","cacheId","__privateGet","useCoingeckoProxy","tokenAddresses","assetPlatformId","marketCap","vol24","change24","lastUpdated","shouldThrow","rawData","number","object","record","CURRENCY_EXCHANGE_RATES_URL","CURRENCY_EXCHANGE_RATES_FALLBACK_URL","ExchangeRateSchema","exchangeRateApiClient","exchangeRateFallbackApiClient","DetailItemType","currencyItem","label","value","maxDecimals","symbol","linkItem","addressItem","extractTokenMarketData","coinId","coinData","getBalances","addresses","withScripts","tokenService","coingeckoTokenId","marketData","priceInCurrency","balanceInSatoshis","utxos","unconfirmedBalanceInSatoshis","utxosUnconfirmed","balance","balanceInCurrency","balanceDisplayValue","unconfirmedBalance","unconfirmedBalanceInCurrency","acc","accountBalance","getBech32AddressFromXPub","getBtcAddressFromPubKey","networks","NetworkVMType","WalletType","getAddress","accountIndex","xpub","walletType","pubKeyBuffer","z","paramsSchema","parseRequestParams","params","isBtcBalance","hasUtxos","hasLocked","hasUnlockedUnstaked","createTransferTx","calculateGasLimit","fee","feeRate","bitcoinSendTransaction","request","approvalController","dappInfo","rawParams","success","parseError","btcBalance","to","from","amount","inputs","outputs","displayData","signingData","txHash","getTxHash","error","waitForTransactionReceipt","onTransactionConfirmed","onTransactionReverted","requestId","_approvalController","BitcoinModule"],"mappings":"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","sourcesContent":["import type {\n Module,\n Manifest,\n NetworkFees,\n GetTransactionHistory,\n RpcRequest,\n Network,\n Environment,\n GetBalancesParams,\n GetAddressParams,\n GetAddressResponse,\n ApprovalController,\n} from '@avalabs/vm-module-types';\nimport { RpcMethod, parseManifest } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { getEnv } from './env';\n\nimport ManifestJson from '../manifest.json';\nimport { getNetworkFee } from './handlers/get-network-fee/get-network-fee';\nimport { getTransactionHistory } from './handlers/get-transaction-history/get-transaction-history';\nimport { getBalances } from './handlers/get-balances/get-balances';\nimport { getAddress } from './handlers/get-address/get-address';\nimport { bitcoinSendTransaction } from './handlers/bitcoin-send-transaction/bitcoin-send-transaction';\nimport type { BitcoinProvider } from '@avalabs/core-wallets-sdk';\nimport { getProvider } from './utils/get-provider';\n\nexport class BitcoinModule implements Module {\n #proxyApiUrl: string;\n #approvalController: ApprovalController;\n\n constructor({\n environment,\n approvalController,\n }: {\n environment: Environment;\n approvalController: ApprovalController;\n }) {\n const { proxyApiUrl } = getEnv(environment);\n\n this.#approvalController = approvalController;\n this.#proxyApiUrl = proxyApiUrl;\n }\n\n getProvider(network: Network): BitcoinProvider {\n return getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl: this.#proxyApiUrl,\n });\n }\n\n getAddress({ accountIndex, xpub, isTestnet, walletType }: GetAddressParams): Promise<GetAddressResponse> {\n return getAddress({ accountIndex, xpub, isTestnet, walletType });\n }\n\n getBalances({ addresses, currency, network, storage }: GetBalancesParams) {\n return getBalances({\n addresses,\n currency,\n network,\n proxyApiUrl: this.#proxyApiUrl,\n storage,\n });\n }\n\n getManifest(): Manifest | undefined {\n const result = parseManifest(ManifestJson);\n return result.success ? result.data : undefined;\n }\n\n getNetworkFee(network: Network): Promise<NetworkFees> {\n return getNetworkFee({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl: this.#proxyApiUrl,\n });\n }\n\n async getTransactionHistory({ address, network }: GetTransactionHistory) {\n return {\n transactions: await getTransactionHistory({\n address,\n network,\n proxyApiUrl: this.#proxyApiUrl,\n }),\n };\n }\n\n getTokens(_: Network) {\n return Promise.resolve([]);\n }\n\n async onRpcRequest(request: RpcRequest, network: Network) {\n switch (request.method) {\n case RpcMethod.BITCOIN_SEND_TRANSACTION:\n return bitcoinSendTransaction({\n request,\n network,\n approvalController: this.#approvalController,\n proxyApiUrl: this.#proxyApiUrl,\n });\n default:\n return { error: rpcErrors.methodNotSupported(`Method ${request.method} not supported`) };\n }\n }\n}\n","import { Environment } from '@avalabs/vm-module-types';\n\ntype Env = {\n glacierApiUrl: string;\n proxyApiUrl: string;\n};\n\nexport const prodEnv: Env = {\n glacierApiUrl: 'https://glacier-api.avax.network',\n proxyApiUrl: 'https://proxy-api.avax.network',\n};\n\nexport const devEnv: Env = {\n glacierApiUrl: 'https://glacier-api-dev.avax.network',\n proxyApiUrl: 'https://proxy-api-dev.avax.network',\n};\n\nexport const getEnv = (environment: Environment): Env => {\n switch (environment) {\n case Environment.PRODUCTION:\n return prodEnv;\n case Environment.DEV:\n return devEnv;\n }\n};\n","{\n \"name\": \"Bitcoin\",\n \"description\": \"\",\n \"version\": \"0.0.1\",\n \"sources\": {\n \"module\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/bundle.js\",\n \"packageName\": \"@avalabs/bitcoin-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n },\n \"provider\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/provider.js\",\n \"packageName\": \"@avalabs/bitcoin-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n }\n },\n \"network\": {\n \"chainIds\": [\"bip122:000000000019d6689c085ae165831e93\", \"bip122:000000000933ea01ad0ee984209779ba\"],\n \"namespaces\": [\"bip122\"]\n },\n \"cointype\": \"0\",\n \"permissions\": {\n \"rpc\": {\n \"dapps\": true,\n \"methods\": [\"bitcoin_sendTransaction\"]\n }\n },\n \"manifestVersion\": \"0.0\"\n}\n","import { BitcoinProvider } from '@avalabs/core-wallets-sdk';\n\ntype ProviderParams = {\n isTestnet: boolean;\n proxyApiUrl: string;\n};\n\nexport const getProvider = ({ isTestnet, proxyApiUrl }: ProviderParams): BitcoinProvider =>\n new BitcoinProvider(\n !isTestnet,\n undefined,\n `${proxyApiUrl}/proxy/nownodes/${isTestnet ? 'btcbook-testnet' : 'btcbook'}`,\n `${proxyApiUrl}/proxy/nownodes/${isTestnet ? 'btc-testnet' : 'btc'}`,\n\n // The Glacier API key is only needed in development to bypass rate limits.\n // It should never be used in production.\n process.env.GLACIER_API_KEY ? { token: process.env.GLACIER_API_KEY } : {},\n );\n","import type { NetworkFees } from '@avalabs/vm-module-types';\n\nimport { getProvider } from '../../utils/get-provider';\n\n/**\n * Returns {@link NetworkFees} based on `estimatesmartfee` RPC call\n */\nexport async function getNetworkFee({\n isTestnet,\n proxyApiUrl,\n}: {\n isTestnet: boolean;\n proxyApiUrl: string;\n}): Promise<NetworkFees> {\n const provider = getProvider({\n isTestnet,\n proxyApiUrl,\n });\n\n const { high, low, medium } = await provider.getFeeRates();\n\n return {\n low: {\n maxFeePerGas: BigInt(low),\n },\n medium: {\n maxFeePerGas: BigInt(medium),\n },\n high: {\n maxFeePerGas: BigInt(high),\n },\n isFixedFee: false,\n };\n}\n","import { TokenType, TransactionType, type Network, type Transaction } from '@avalabs/vm-module-types';\nimport type { BitcoinHistoryTx } from '@avalabs/core-wallets-sdk';\n\ntype ConverterOptions = {\n address: string;\n network: Network;\n};\n\nexport const convertBtcTransaction = (tx: BitcoinHistoryTx, { address, network }: ConverterOptions): Transaction => {\n const { explorerUrl, networkToken } = network;\n const txAddress = tx.addresses[0] ?? '';\n\n return {\n chainId: network.chainId.toString(),\n explorerLink: `${explorerUrl}/tx/${tx.hash}`,\n from: tx.isSender ? address : txAddress,\n gasUsed: tx.fee.toString(),\n hash: tx.hash,\n isContractCall: false,\n isIncoming: !tx.isSender,\n isOutgoing: tx.isSender,\n isSender: tx.isSender,\n timestamp: tx.receivedTime * 1000,\n to: tx.isSender ? txAddress : address,\n tokens: [\n {\n amount: (Math.abs(tx.amount) / 10 ** networkToken.decimals).toString(),\n decimal: networkToken.decimals.toString(),\n name: networkToken.name,\n symbol: networkToken.symbol,\n type: TokenType.NATIVE,\n },\n ],\n txType: tx.isSender ? TransactionType.SEND : TransactionType.RECEIVE,\n };\n};\n","import type { Network } from '@avalabs/vm-module-types';\n\nimport { getProvider } from '../../utils/get-provider';\n\nimport { convertBtcTransaction } from './convert-btc-transaction';\n\ntype GetBtcTransactionHistoryOptions = {\n network: Network;\n address: string;\n proxyApiUrl: string;\n};\n\nexport const getTransactionHistory = async ({ address, network, proxyApiUrl }: GetBtcTransactionHistoryOptions) => {\n const provider = getProvider({ isTestnet: Boolean(network.isTestnet), proxyApiUrl });\n const rawHistory = await provider.getTxHistory(address);\n\n return rawHistory.map((tx) =>\n convertBtcTransaction(tx, {\n address,\n network,\n }),\n );\n};\n","import { type GetBalancesParams, TokenType, type TokenWithBalanceBTC } from '@avalabs/vm-module-types';\nimport { TokenUnit } from '@avalabs/core-utils-sdk';\nimport type { VsCurrencyType } from '@avalabs/core-coingecko-sdk';\n\nimport { TokenService } from '@internal/utils';\n\nimport { getProvider } from '../../utils/get-provider';\nimport { extractTokenMarketData } from '../../utils/extract-token-market-data';\n\ntype GetBtcBalancesResponse = Record<string, Record<string, TokenWithBalanceBTC>>;\n\ntype GetBTCBalancesParams = Omit<GetBalancesParams, 'currency'> & {\n proxyApiUrl: string;\n withScripts?: boolean;\n currency?: string;\n};\n\nexport const getBalances = async ({\n addresses,\n currency,\n network,\n withScripts,\n proxyApiUrl,\n storage,\n}: GetBTCBalancesParams): Promise<GetBtcBalancesResponse> => {\n const provider = getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl,\n });\n\n const tokenService = new TokenService({ proxyApiUrl, storage });\n const coingeckoTokenId = network.pricingProviders?.coingecko.nativeTokenId;\n const withPrices = typeof currency === 'string' && typeof coingeckoTokenId === 'string';\n const marketData = withPrices\n ? await tokenService.getSimplePrice({\n coinIds: [coingeckoTokenId],\n currencies: [currency] as VsCurrencyType[],\n })\n : undefined;\n const { priceInCurrency, change24, marketCap, vol24 } = extractTokenMarketData(\n coingeckoTokenId ?? '',\n currency,\n marketData,\n );\n\n const balances = await Promise.allSettled(\n addresses.map(async (address) => {\n const {\n balance: balanceInSatoshis,\n utxos,\n balanceUnconfirmed: unconfirmedBalanceInSatoshis,\n utxosUnconfirmed,\n } = await provider.getUtxoBalance(address, withScripts);\n\n const balance = new TokenUnit(balanceInSatoshis, network.networkToken.decimals, network.networkToken.symbol);\n const balanceInCurrency = priceInCurrency !== undefined ? balance.mul(priceInCurrency) : undefined;\n const balanceDisplayValue = balance.toDisplay();\n\n const unconfirmedBalance = new TokenUnit(\n unconfirmedBalanceInSatoshis,\n network.networkToken.decimals,\n network.networkToken.symbol,\n );\n const unconfirmedBalanceInCurrency =\n priceInCurrency !== undefined ? unconfirmedBalance.mul(priceInCurrency) : undefined;\n\n const symbol = network.networkToken.symbol;\n\n return {\n [address]: {\n [symbol]: {\n ...network.networkToken,\n utxos,\n utxosUnconfirmed,\n coingeckoId: coingeckoTokenId ?? '',\n type: TokenType.NATIVE,\n balance: balance.toSubUnit(),\n balanceDisplayValue,\n balanceInCurrency: balanceInCurrency?.toDisplay({ fixedDp: 2, asNumber: true }),\n balanceCurrencyDisplayValue: balanceInCurrency?.toDisplay({ fixedDp: 2 }),\n priceInCurrency,\n marketCap,\n vol24,\n change24,\n unconfirmedBalance: unconfirmedBalance.toSubUnit(),\n unconfirmedBalanceDisplayValue: unconfirmedBalance.toDisplay(),\n unconfirmedBalanceInCurrency: unconfirmedBalanceInCurrency?.toDisplay({\n fixedDp: 2,\n asNumber: true,\n }),\n unconfirmedBalanceCurrencyDisplayValue: unconfirmedBalanceInCurrency?.toDisplay({ fixedDp: 2 }),\n },\n },\n };\n }),\n );\n\n return balances.reduce((acc, accountBalance) => {\n if (accountBalance.status === 'rejected') {\n return acc;\n }\n\n return {\n ...acc,\n ...accountBalance.value,\n };\n }, {});\n};\n","import {\n VsCurrencyType,\n getBasicCoingeckoHttp,\n simplePrice,\n simpleTokenPrice,\n type SimplePriceParams,\n} from '@avalabs/core-coingecko-sdk';\nimport type { Storage, RawSimplePriceResponse, SimplePriceResponse } from '@avalabs/vm-module-types';\nimport { coingeckoRetry } from '../../utils/coingecko-retry';\nimport { arrayHash } from '../../utils/array-hash';\nimport { coingeckoProxyClient } from './coingecko-proxy-client';\n\nconst coingeckoBasicClient = getBasicCoingeckoHttp();\n\nexport class TokenService {\n #storage?: Storage;\n #proxyApiUrl: string;\n\n constructor({ storage, proxyApiUrl }: { proxyApiUrl: string; storage?: Storage }) {\n this.#storage = storage;\n this.#proxyApiUrl = proxyApiUrl;\n }\n\n /**\n * Get token price with market data first on coingecko (free tier) directly,\n * if we get 429 error, retry it on coingecko proxy (paid service)\n * @returns token price with market data\n */\n async getSimplePrice({\n coinIds = [],\n currencies = [VsCurrencyType.USD],\n }: SimplePriceParams): Promise<SimplePriceResponse | undefined> {\n let data: SimplePriceResponse | undefined;\n\n const key = coinIds ? `${arrayHash(coinIds)}-${currencies.toString()}` : `${currencies.toString()}`;\n\n const cacheId = `getSimplePrice-${key}`;\n\n data = this.#storage?.get?.<SimplePriceResponse>(cacheId);\n\n if (data) return data;\n\n try {\n data = await coingeckoRetry((useCoingeckoProxy) =>\n this.simplePrice({\n coinIds,\n currencies,\n marketCap: true,\n vol24: true,\n change24: true,\n useCoingeckoProxy,\n }),\n );\n } catch {\n data = undefined;\n }\n this.#storage?.set?.(cacheId, data);\n return data;\n }\n\n /**\n * Get token price with market data for a list of addresses\n * @param tokenAddresses the token addresses\n * @param assetPlatformId The platform id for all the tokens in the list\n * @param currency the currency to be used\n * @returns a list of token price with market data\n */\n async getPricesByAddresses(\n tokenAddresses: string[],\n assetPlatformId: string,\n currency: VsCurrencyType = VsCurrencyType.USD,\n ): Promise<SimplePriceResponse | undefined> {\n let data: SimplePriceResponse | undefined;\n\n const key = `${arrayHash(tokenAddresses)}-${assetPlatformId}-${currency}`;\n\n const cacheId = `getPricesWithMarketDataByAddresses-${key}`;\n data = this.#storage?.get?.<SimplePriceResponse>(cacheId);\n\n if (data) return data;\n\n try {\n data = await coingeckoRetry((useCoingeckoProxy) =>\n this.fetchPricesByAddresses({\n assetPlatformId,\n tokenAddresses,\n currency,\n useCoingeckoProxy,\n }),\n );\n } catch {\n data = undefined;\n }\n this.#storage?.set?.(cacheId, data);\n return data;\n }\n\n private async fetchPricesByAddresses({\n assetPlatformId,\n tokenAddresses,\n currency = VsCurrencyType.USD,\n useCoingeckoProxy = false,\n }: {\n assetPlatformId: string;\n tokenAddresses: string[];\n currency: VsCurrencyType;\n useCoingeckoProxy?: boolean;\n }): Promise<SimplePriceResponse> {\n if (useCoingeckoProxy) {\n return coingeckoProxyClient(this.#proxyApiUrl).simplePriceByContractAddresses(undefined, {\n params: {\n id: assetPlatformId,\n },\n queries: {\n contract_addresses: tokenAddresses,\n vs_currencies: [currency],\n include_market_cap: true,\n include_24hr_vol: true,\n include_24hr_change: true,\n },\n });\n }\n\n return simpleTokenPrice(coingeckoBasicClient, {\n assetPlatformId,\n tokenAddresses,\n currencies: [currency],\n marketCap: true,\n vol24: true,\n change24: true,\n });\n }\n\n private async simplePrice({\n coinIds = [],\n currencies = [VsCurrencyType.USD],\n marketCap = false,\n vol24 = false,\n change24 = false,\n lastUpdated = false,\n useCoingeckoProxy = false,\n shouldThrow = true,\n }: SimplePriceParams & { useCoingeckoProxy?: boolean }): Promise<SimplePriceResponse> {\n if (useCoingeckoProxy) {\n const rawData = await coingeckoProxyClient(this.#proxyApiUrl).simplePrice(undefined, {\n queries: {\n ids: coinIds?.join(','),\n vs_currencies: currencies.join(','),\n include_market_cap: String(marketCap),\n include_24hr_vol: String(vol24),\n include_24hr_change: String(change24),\n include_last_updated_at: String(lastUpdated),\n },\n });\n return this.transformSimplePriceResponse(rawData, currencies);\n }\n return simplePrice(coingeckoBasicClient, {\n coinIds,\n currencies,\n marketCap,\n vol24,\n change24,\n lastUpdated,\n shouldThrow,\n });\n }\n\n private transformSimplePriceResponse = (\n data: RawSimplePriceResponse,\n currencies = [VsCurrencyType.USD],\n ): SimplePriceResponse => {\n const formattedData: SimplePriceResponse = {};\n Object.keys(data).forEach((id) => {\n const tokenData = data[id];\n formattedData[id] = {};\n currencies.forEach((currency: VsCurrencyType) => {\n formattedData[id] = {\n [currency]: {\n price: tokenData?.[currency],\n change24: tokenData?.[`${currency}_24h_change`],\n vol24: tokenData?.[`${currency}_24h_vol`],\n marketCap: tokenData?.[`${currency}_market_cap`],\n },\n };\n });\n });\n return formattedData;\n };\n}\n","const DEFAULT_MAX_RETRIES = 10;\n\ntype RetryParams<T> = {\n operation: (retryIndex: number) => Promise<T>;\n isSuccess: (result: T) => boolean;\n maxRetries?: number;\n backoffPolicy?: RetryBackoffPolicyInterface;\n};\n/*\n * Retries an operation with defined backoff policy.\n *\n * @param operation - The operation to retry.\n * @param isSuccess - The predicate to check if the operation succeeded.\n * @param maxRetries - The maximum number of retries.\n * @param backoffPolicy - Function to generate delay time based on current retry count.\n *\n * @returns The result of the operation.\n * @throws An error if the operation fails after the maximum number of retries.\n *\n * @example\n * const result = await retry(\n * async () => {\n * const response = await fetch('https://example.com')\n * return response.json()\n * },\n * result => result.status === 200\n * )\n */\nexport const retry = async <T>({\n operation,\n isSuccess,\n maxRetries = DEFAULT_MAX_RETRIES,\n backoffPolicy = RetryBackoffPolicy.exponential(),\n}: RetryParams<T>): Promise<T> => {\n let backoffPeriodMillis = 0;\n let retries = 0;\n let lastError: unknown;\n\n while (retries < maxRetries) {\n if (retries > 0) {\n await delay(backoffPeriodMillis);\n }\n\n try {\n const result = await operation(retries);\n\n if (isSuccess(result)) {\n return result;\n }\n } catch (err) {\n // when the operation throws an error, we still retry\n lastError = err;\n }\n\n backoffPeriodMillis = backoffPolicy(retries);\n retries++;\n }\n\n const errorMessage = lastError ? `Max retry exceeded. ${lastError}` : 'Max retry exceeded.';\n\n throw new Error(errorMessage);\n};\n\ntype RetryBackoffPolicyInterface = (retryIndex: number) => number;\n\nexport class RetryBackoffPolicy {\n static exponential(): RetryBackoffPolicyInterface {\n return (retryIndex: number): number => {\n return Math.pow(2, retryIndex) * 1000;\n };\n }\n\n static constant(secondsToDelay: number): RetryBackoffPolicyInterface {\n return (_: number): number => {\n return secondsToDelay * 1000;\n };\n }\n\n static constantMs(msToDelay: number): RetryBackoffPolicyInterface {\n return (_: number): number => {\n return msToDelay;\n };\n }\n}\n\nfunction delay(ms: number) {\n return new Promise((r) => setTimeout(r, ms));\n}\n","import { RetryBackoffPolicy, retry } from './retry';\n\ntype Error = {\n status: {\n error_code: number;\n error_message: string;\n };\n};\n\nexport const coingeckoRetry = <T>(\n operation: (useCoingeckoProxy: boolean) => Promise<T | Error>,\n): Promise<T | undefined> => {\n return retry({\n operation: (retryIndex: number) => operation(retryIndex > 0),\n maxRetries: 2,\n backoffPolicy: RetryBackoffPolicy.constant(1),\n isSuccess: (response: T | Error) => {\n const errorStatus = (response as Error)?.status;\n return errorStatus?.error_code !== 429;\n },\n }) as Promise<T | undefined>;\n};\n","export function charsum(s: string): number {\n let i,\n sum = 0;\n for (i = 0; i < s.length; i++) {\n sum += s.charCodeAt(i) * (i + 1);\n }\n return sum;\n}\n","import { charsum } from './charsum';\n\n// from https://stackoverflow.com/a/25105589\nexport function arrayHash(array: string[]): string {\n let i,\n sum = 0;\n for (i = 0; i < array.length; i++) {\n const cs = charsum(array[i] ?? '');\n sum = sum + 65027 / cs;\n }\n return ('' + sum).slice(0, 16);\n}\n","import { Zodios } from '@zodios/core';\nimport { RawSimplePriceResponseSchema, SimplePriceResponseSchema } from '@avalabs/vm-module-types';\nimport { boolean, string } from 'zod';\n\nexport const coingeckoProxyClient = (proxyApiUrl: string) =>\n new Zodios(\n `${proxyApiUrl}/proxy/coingecko`,\n [\n {\n method: 'post',\n path: '/simple/price',\n parameters: [\n { name: 'ids', type: 'Query', schema: string() },\n { name: 'vs_currencies', type: 'Query', schema: string() },\n {\n name: 'include_market_cap',\n type: 'Query',\n schema: string().optional(),\n },\n {\n name: 'include_24hr_vol',\n type: 'Query',\n schema: string().optional(),\n },\n {\n name: 'include_24hr_change',\n type: 'Query',\n schema: string().optional(),\n },\n {\n name: 'include_last_updated_at',\n type: 'Query',\n schema: string().optional(),\n },\n ],\n alias: 'simplePrice',\n response: RawSimplePriceResponseSchema,\n },\n {\n method: 'post',\n path: '/simple/token_price/:id',\n parameters: [\n { name: 'id', type: 'Path', schema: string() },\n { name: 'contract_addresses', type: 'Query', schema: string().array() },\n { name: 'vs_currencies', type: 'Query', schema: string().array() },\n {\n name: 'include_market_cap',\n type: 'Query',\n schema: boolean().optional(),\n },\n {\n name: 'include_24hr_vol',\n type: 'Query',\n schema: boolean().optional(),\n },\n {\n name: 'include_24hr_change',\n type: 'Query',\n schema: boolean().optional(),\n },\n ],\n alias: 'simplePriceByContractAddresses',\n response: SimplePriceResponseSchema,\n },\n ],\n {\n axiosConfig: {\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n },\n );\n","import { Zodios } from '@zodios/core';\nimport z, { number, object, record, string } from 'zod';\n\nconst CURRENCY_EXCHANGE_RATES_URL =\n 'https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/usd.min.json';\n\nconst CURRENCY_EXCHANGE_RATES_FALLBACK_URL = 'https://latest.currency-api.pages.dev/v1/currencies/usd.min.json';\n\nconst ExchangeRateSchema = object({\n date: string(),\n usd: record(number()),\n});\n\ntype ExchangeRate = z.infer<typeof ExchangeRateSchema>;\n\nconst exchangeRateApiClient = new Zodios(CURRENCY_EXCHANGE_RATES_URL, [\n {\n method: 'get',\n path: '',\n alias: 'getExchangeRates',\n response: ExchangeRateSchema,\n },\n]);\n\nconst exchangeRateFallbackApiClient = new Zodios(CURRENCY_EXCHANGE_RATES_FALLBACK_URL, [\n {\n method: 'get',\n path: '',\n alias: 'getExchangeRates',\n response: ExchangeRateSchema,\n },\n]);\n\nexport const getExchangeRates = async (): Promise<ExchangeRate> => {\n try {\n return await exchangeRateApiClient.getExchangeRates();\n } catch {\n return await exchangeRateFallbackApiClient.getExchangeRates();\n }\n};\n","import {\n type AddressItem,\n type CurrencyItem,\n type NodeIDItem,\n type TextItem,\n type DataItem,\n type DateItem,\n type LinkItemValue,\n DetailItemType,\n type LinkItem,\n} from '@avalabs/vm-module-types';\n\nexport const currencyItem = (label: string, value: bigint, maxDecimals: number, symbol: string): CurrencyItem => ({\n label,\n type: DetailItemType.CURRENCY,\n value,\n maxDecimals,\n symbol,\n});\n\nexport const textItem = (\n label: string,\n value: string,\n alignment: 'horizontal' | 'vertical' = 'horizontal',\n): TextItem => ({\n label,\n alignment,\n type: DetailItemType.TEXT,\n value,\n});\n\nexport const linkItem = (label: string, value: LinkItemValue): LinkItem => ({\n label,\n value,\n type: DetailItemType.LINK,\n});\n\nexport const addressItem = (label: string, value: string): AddressItem => ({\n label,\n type: DetailItemType.ADDRESS,\n value,\n});\n\nexport const nodeIDItem = (label: string, value: string): NodeIDItem => ({\n label,\n type: DetailItemType.NODE_ID,\n value,\n});\n\nexport const dataItem = (label: string, value: string): DataItem => ({\n label,\n type: DetailItemType.DATA,\n value,\n});\n\nexport const dateItem = (label: string, value: string): DateItem => ({\n label,\n type: DetailItemType.DATE,\n value,\n});\n","import type { SimplePriceResponse, TokenMarketData } from '@avalabs/vm-module-types';\n\nexport const extractTokenMarketData = (\n coinId: string,\n currency?: string,\n data?: SimplePriceResponse,\n): TokenMarketData => {\n const coinData = data?.[coinId]?.[currency ?? ''] ?? {};\n\n return {\n priceInCurrency: coinData.price ?? undefined,\n marketCap: coinData.marketCap ?? undefined,\n vol24: coinData.vol24 ?? undefined,\n change24: coinData.change24 ?? undefined,\n };\n};\n","import type { GetAddressParams, GetAddressResponse } from '@avalabs/vm-module-types';\nimport { getBech32AddressFromXPub, getBtcAddressFromPubKey } from '@avalabs/core-wallets-sdk';\nimport { networks } from 'bitcoinjs-lib';\nimport { NetworkVMType, WalletType } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\n\ntype GetAddress = Omit<GetAddressParams, 'xpubXP'>;\n\nexport const getAddress = async ({\n accountIndex,\n xpub,\n isTestnet,\n walletType,\n}: GetAddress): Promise<GetAddressResponse> => {\n switch (walletType) {\n case WalletType.Mnemonic:\n case WalletType.Ledger:\n case WalletType.Keystone: {\n return {\n [NetworkVMType.BITCOIN]: getBech32AddressFromXPub(\n xpub,\n accountIndex,\n isTestnet ? networks.testnet : networks.bitcoin,\n ),\n };\n }\n case WalletType.LedgerLive:\n case WalletType.Seedless: {\n const pubKeyBuffer = Buffer.from(xpub, 'hex');\n return {\n [NetworkVMType.BITCOIN]: getBtcAddressFromPubKey(pubKeyBuffer, isTestnet ? networks.testnet : networks.bitcoin),\n };\n }\n default:\n throw rpcErrors.invalidParams(`Unsupported wallet type: ${walletType}`);\n }\n};\n","import {\n RpcMethod,\n type ApprovalController,\n type DisplayData,\n type Hex,\n type Network,\n type RpcRequest,\n type SigningData,\n type SigningResult,\n} from '@avalabs/vm-module-types';\nimport { parseRequestParams } from './schema';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { getProvider } from '../../utils/get-provider';\nimport { getBalances } from '../get-balances/get-balances';\nimport { isBtcBalance } from '../../utils/is-btc-balance';\nimport { BitcoinProvider, createTransferTx, type BitcoinInputUTXO } from '@avalabs/core-wallets-sdk';\nimport { calculateGasLimit } from '../../utils/calculate-gas-limit';\nimport { addressItem, currencyItem } from '@internal/utils';\nimport { linkItem } from '@internal/utils/src/utils/detail-item';\n\ntype BitcoinSendTransactionParams = {\n request: RpcRequest;\n network: Network;\n approvalController: ApprovalController;\n proxyApiUrl: string;\n};\n\nexport const bitcoinSendTransaction = async ({\n request,\n network,\n approvalController,\n proxyApiUrl,\n}: BitcoinSendTransactionParams) => {\n const { dappInfo, params: rawParams } = request;\n\n const { success, data: params, error: parseError } = parseRequestParams(rawParams);\n\n if (!success) {\n console.error('invalid params', parseError);\n return {\n error: rpcErrors.invalidParams({ message: 'Transaction params are invalid', data: { cause: parseError } }),\n };\n }\n\n const balances = await getBalances({ addresses: [params.from], network, proxyApiUrl, withScripts: true });\n const btcBalance = balances?.[params.from]?.[network.networkToken.symbol];\n\n if (!isBtcBalance(btcBalance)) {\n return {\n error: rpcErrors.internal('Balance for the source account is not available'),\n };\n }\n\n const provider = getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl,\n });\n\n const { to, from, amount, feeRate } = params;\n\n const { inputs, outputs, fee } = createTransferTx(\n to,\n from,\n amount,\n feeRate,\n btcBalance.utxos as BitcoinInputUTXO[], // we asked for scripts in getBalances() call\n provider.getNetwork(),\n );\n\n if (!inputs || !outputs) {\n return {\n error: rpcErrors.internal('Unable to create transaction'),\n };\n }\n\n const displayData: DisplayData = {\n title: 'Approve Transaction',\n network: {\n chainId: network.chainId,\n name: network.chainName,\n logoUri: network.logoUri,\n },\n details: [\n {\n title: 'Transaction Details',\n items: [\n linkItem('Website', dappInfo),\n addressItem('From', from),\n addressItem('To', to),\n currencyItem('Amount', BigInt(amount), network.networkToken.decimals, network.networkToken.symbol),\n ],\n },\n ],\n networkFeeSelector: true,\n };\n\n const signingData: SigningData = {\n type: RpcMethod.BITCOIN_SEND_TRANSACTION,\n account: from,\n data: {\n to,\n amount,\n fee,\n feeRate,\n gasLimit: calculateGasLimit(fee, feeRate),\n inputs,\n outputs,\n balance: btcBalance,\n },\n };\n\n const response = await approvalController.requestApproval({ request, displayData, signingData });\n\n if ('error' in response) {\n return {\n error: response.error,\n };\n }\n\n let txHash;\n\n try {\n txHash = await getTxHash(provider, response);\n } catch (error) {\n return {\n error: rpcErrors.internal({ message: 'Unable to get transaction hash', data: { cause: error } }),\n };\n }\n\n waitForTransactionReceipt({\n provider,\n txHash: txHash as Hex,\n onTransactionConfirmed: approvalController.onTransactionConfirmed,\n onTransactionReverted: approvalController.onTransactionReverted,\n // Pass the requestId so that client apps can pair the transaction\n // status changes back to their respective requests for better tracking.\n requestId: request.requestId,\n });\n\n return {\n result: txHash,\n };\n};\n\nconst getTxHash = async (provider: BitcoinProvider, response: SigningResult) => {\n if ('txHash' in response) {\n return response.txHash;\n }\n\n return provider.issueRawTx(response.signedData);\n};\n\nconst waitForTransactionReceipt = async ({\n provider,\n txHash,\n onTransactionConfirmed,\n onTransactionReverted,\n requestId,\n}: {\n provider: BitcoinProvider;\n txHash: Hex;\n onTransactionConfirmed: (txHash: Hex, requestId: string) => void;\n onTransactionReverted: (txHash: Hex, requestId: string) => void;\n requestId: string;\n}) => {\n try {\n await provider.waitForTx(txHash);\n onTransactionConfirmed(txHash, requestId);\n } catch (err) {\n console.error(err);\n onTransactionReverted(txHash, requestId);\n }\n};\n","import { z } from 'zod';\n\nconst paramsSchema = z.object({\n from: z.string(),\n to: z.string(),\n amount: z.number(),\n feeRate: z.number(),\n});\n\nexport const parseRequestParams = (params: unknown) => {\n return paramsSchema.safeParse(params);\n};\n\nexport type BitcoinSendTransactionParams = z.infer<typeof paramsSchema>;\n","import type { TokenWithBalance, TokenWithBalanceBTC } from '@avalabs/vm-module-types';\n\nexport const isBtcBalance = (balance?: TokenWithBalance): balance is TokenWithBalanceBTC => {\n if (!balance) {\n return false;\n }\n\n const hasUtxos = 'utxos' in balance; // BTC, P-Chain or X-Chain\n const hasLocked = 'locked' in balance; // X-Chain only\n const hasUnlockedUnstaked = 'unlockedUnstaked' in balance; // P-Chain only\n\n return hasUtxos && !hasUnlockedUnstaked && !hasLocked;\n};\n","// The transaction's byte size is for BTC as gasLimit is for EVM.\n// Bitcoin's formula for fee is `transactionByteLength * feeRate`.\n// Since we know the `fee` and the `feeRate`, we can get the transaction's\n// byte length by division.\nexport const calculateGasLimit = (fee: number, feeRate: number): number => {\n return fee / feeRate;\n};\n"]}
package/dist/index.js CHANGED
@@ -7,8 +7,8 @@ import { Zodios } from '@zodios/core';
7
7
  import { object, string, record, number, z as z$1, boolean } from 'zod';
8
8
  import { networks } from 'bitcoinjs-lib';
9
9
 
10
- var ke=Object.defineProperty;var ve=(r,e,t)=>e in r?ke(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var Z=(r,e,t)=>(ve(r,typeof e!="symbol"?e+"":e,t),t),J=(r,e,t)=>{if(!e.has(r))throw TypeError("Cannot "+t)};var c=(r,e,t)=>(J(r,e,"read from private field"),t?t.call(r):e.get(r)),P=(r,e,t)=>{if(e.has(r))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(r):e.set(r,t);},x=(r,e,t,n)=>(J(r,e,"write to private field"),n?n.call(r,t):e.set(r,t),t);var be={glacierApiUrl:"https://glacier-api.avax.network",proxyApiUrl:"https://proxy-api.avax.network"},Re={glacierApiUrl:"https://glacier-api-dev.avax.network",proxyApiUrl:"https://proxy-api-dev.avax.network"},te=r=>{switch(r){case Environment.PRODUCTION:return be;case Environment.DEV:return Re}};var re={name:"Bitcoin",description:"",version:"0.0.1",sources:{module:{checksum:"",location:{npm:{filePath:"dist/bundle.js",packageName:"@avalabs/bitcoin-module",registry:"https://registry.npmjs.org"}}},provider:{checksum:"",location:{npm:{filePath:"dist/provider.js",packageName:"@avalabs/bitcoin-module",registry:"https://registry.npmjs.org"}}}},network:{chainIds:["bip122:000000000019d6689c085ae165831e93","bip122:000000000933ea01ad0ee984209779ba"],namespaces:["bip122"]},cointype:"0",permissions:{rpc:{dapps:!0,methods:["bitcoin_sendTransaction"]}},manifestVersion:"0.0"};var m=({isTestnet:r,proxyApiUrl:e})=>new BitcoinProvider(!r,void 0,`${e}/proxy/nownodes/${r?"btcbook-testnet":"btcbook"}`,`${e}/proxy/nownodes/${r?"btc-testnet":"btc"}`,process.env.GLACIER_API_KEY?{token:process.env.GLACIER_API_KEY}:{});async function ne({isTestnet:r,proxyApiUrl:e}){let t=m({isTestnet:r,proxyApiUrl:e}),{high:n,low:o,medium:a}=await t.getFeeRates();return {low:{maxFeePerGas:BigInt(o)},medium:{maxFeePerGas:BigInt(a)},high:{maxFeePerGas:BigInt(n)},isFixedFee:!1}}var ae=(r,{address:e,network:t})=>{let{explorerUrl:n,networkToken:o}=t,a=r.addresses[0]??"";return {chainId:t.chainId.toString(),explorerLink:`${n}/tx/${r.hash}`,from:r.isSender?e:a,gasUsed:r.fee.toString(),hash:r.hash,isContractCall:!1,isIncoming:!r.isSender,isOutgoing:r.isSender,isSender:r.isSender,timestamp:r.receivedTime*1e3,to:r.isSender?a:e,tokens:[{amount:(Math.abs(r.amount)/10**o.decimals).toString(),decimal:o.decimals.toString(),name:o.name,symbol:o.symbol,type:TokenType.NATIVE}],txType:r.isSender?TransactionType.SEND:TransactionType.RECEIVE}};var se=async({address:r,network:e,proxyApiUrl:t})=>(await m({isTestnet:!!e.isTestnet,proxyApiUrl:t}).getTxHistory(r)).map(a=>ae(a,{address:r,network:e}));var V=async({operation:r,isSuccess:e,maxRetries:t=10,backoffPolicy:n=B.exponential()})=>{let o=0,a=0,s;for(;a<t;){a>0&&await we(o);try{let i=await r(a);if(e(i))return i}catch(i){s=i;}o=n(a),a++;}let p=s?`Max retry exceeded. ${s}`:"Max retry exceeded.";throw new Error(p)},B=class{static exponential(){return e=>Math.pow(2,e)*1e3}static constant(e){return t=>e*1e3}static constantMs(e){return t=>e}};function we(r){return new Promise(e=>setTimeout(e,r))}var j=r=>V({operation:e=>r(e>0),maxRetries:2,backoffPolicy:B.constant(1),isSuccess:e=>e?.status?.error_code!==429});function ie(r){let e,t=0;for(e=0;e<r.length;e++)t+=r.charCodeAt(e)*(e+1);return t}function Q(r){let e,t=0;for(e=0;e<r.length;e++){let n=ie(r[e]??"");t=t+65027/n;}return (""+t).slice(0,16)}var X=r=>new Zodios(`${r}/proxy/coingecko`,[{method:"post",path:"/simple/price",parameters:[{name:"ids",type:"Query",schema:string()},{name:"vs_currencies",type:"Query",schema:string()},{name:"include_market_cap",type:"Query",schema:string().optional()},{name:"include_24hr_vol",type:"Query",schema:string().optional()},{name:"include_24hr_change",type:"Query",schema:string().optional()},{name:"include_last_updated_at",type:"Query",schema:string().optional()}],alias:"simplePrice",response:RawSimplePriceResponseSchema},{method:"post",path:"/simple/token_price/:id",parameters:[{name:"id",type:"Path",schema:string()},{name:"contract_addresses",type:"Query",schema:string().array()},{name:"vs_currencies",type:"Query",schema:string().array()},{name:"include_market_cap",type:"Query",schema:boolean().optional()},{name:"include_24hr_vol",type:"Query",schema:boolean().optional()},{name:"include_24hr_change",type:"Query",schema:boolean().optional()}],alias:"simplePriceByContractAddresses",response:SimplePriceResponseSchema}],{axiosConfig:{headers:{"Content-Type":"application/json"}}});var ce=getBasicCoingeckoHttp(),f,k,w=class{constructor({storage:e,proxyApiUrl:t}){P(this,f,void 0);P(this,k,void 0);Z(this,"transformSimplePriceResponse",(e,t=[VsCurrencyType.USD])=>{let n={};return Object.keys(e).forEach(o=>{let a=e[o];n[o]={},t.forEach(s=>{n[o]={[s]:{price:a?.[s],change24:a?.[`${s}_24h_change`],vol24:a?.[`${s}_24h_vol`],marketCap:a?.[`${s}_market_cap`]}};});}),n});x(this,f,e),x(this,k,t);}async getSimplePrice({coinIds:e=[],currencies:t=[VsCurrencyType.USD]}){let n,a=`getSimplePrice-${e?`${Q(e)}-${t.toString()}`:`${t.toString()}`}`;if(n=c(this,f)?.get?.(a),n)return n;try{n=await j(s=>this.simplePrice({coinIds:e,currencies:t,marketCap:!0,vol24:!0,change24:!0,useCoingeckoProxy:s}));}catch{n=void 0;}return c(this,f)?.set?.(a,n),n}async getPricesByAddresses(e,t,n=VsCurrencyType.USD){let o,s=`getPricesWithMarketDataByAddresses-${`${Q(e)}-${t}-${n}`}`;if(o=c(this,f)?.get?.(s),o)return o;try{o=await j(p=>this.fetchPricesByAddresses({assetPlatformId:t,tokenAddresses:e,currency:n,useCoingeckoProxy:p}));}catch{o=void 0;}return c(this,f)?.set?.(s,o),o}async fetchPricesByAddresses({assetPlatformId:e,tokenAddresses:t,currency:n=VsCurrencyType.USD,useCoingeckoProxy:o=!1}){return o?X(c(this,k)).simplePriceByContractAddresses(void 0,{params:{id:e},queries:{contract_addresses:t,vs_currencies:[n],include_market_cap:!0,include_24hr_vol:!0,include_24hr_change:!0}}):simpleTokenPrice(ce,{assetPlatformId:e,tokenAddresses:t,currencies:[n],marketCap:!0,vol24:!0,change24:!0})}async simplePrice({coinIds:e=[],currencies:t=[VsCurrencyType.USD],marketCap:n=!1,vol24:o=!1,change24:a=!1,lastUpdated:s=!1,useCoingeckoProxy:p=!1,shouldThrow:i=!0}){if(p){let M=await X(c(this,k)).simplePrice(void 0,{queries:{ids:e?.join(","),vs_currencies:t.join(","),include_market_cap:String(n),include_24hr_vol:String(o),include_24hr_change:String(a),include_last_updated_at:String(s)}});return this.transformSimplePriceResponse(M,t)}return simplePrice(ce,{coinIds:e,currencies:t,marketCap:n,vol24:o,change24:a,lastUpdated:s,shouldThrow:i})}};f=new WeakMap,k=new WeakMap;var Fe="https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/usd.min.json",$e="https://latest.currency-api.pages.dev/v1/currencies/usd.min.json",me=object({date:string(),usd:record(number())});new Zodios(Fe,[{method:"get",path:"",alias:"getExchangeRates",response:me}]);new Zodios($e,[{method:"get",path:"",alias:"getExchangeRates",response:me}]);var z=(r,e,t,n)=>({label:r,type:DetailItemType.CURRENCY,value:e,maxDecimals:t,symbol:n}),K=(r,e,t="horizontal")=>({label:r,alignment:t,type:DetailItemType.TEXT,value:e}),U=(r,e)=>({label:r,type:DetailItemType.ADDRESS,value:e});var le=(r,e,t)=>{let n=t?.[r]?.[e??""]??{};return {priceInCurrency:n.price??void 0,marketCap:n.marketCap??void 0,vol24:n.vol24??void 0,change24:n.change24??void 0}};var N=async({addresses:r,currency:e,network:t,withScripts:n,proxyApiUrl:o,storage:a})=>{let s=m({isTestnet:!!t.isTestnet,proxyApiUrl:o}),p=new w({proxyApiUrl:o,storage:a}),i=t.pricingProviders?.coingecko.nativeTokenId,v=typeof e=="string"&&typeof i=="string"?await p.getSimplePrice({coinIds:[i],currencies:[e]}):void 0,{priceInCurrency:l,change24:b,marketCap:R,vol24:S}=le(i??"",e,v);return (await Promise.allSettled(r.map(async y=>{let{balance:g,utxos:D,balanceUnconfirmed:F,utxosUnconfirmed:$}=await s.getUtxoBalance(y,n),h=new TokenUnit(g,t.networkToken.decimals,t.networkToken.symbol),T=l!==void 0?h.mul(l):void 0,O=h.toDisplay(),L=new TokenUnit(F,t.networkToken.decimals,t.networkToken.symbol),Y=l!==void 0?L.mul(l):void 0,xe=t.networkToken.symbol;return {[y]:{[xe]:{...t.networkToken,utxos:D,utxosUnconfirmed:$,coingeckoId:i??"",type:TokenType.NATIVE,balance:h.toSubUnit(),balanceDisplayValue:O,balanceInCurrency:T?.toDisplay({fixedDp:2,asNumber:!0}),balanceCurrencyDisplayValue:T?.toDisplay({fixedDp:2}),priceInCurrency:l,marketCap:R,vol24:S,change24:b,unconfirmedBalance:L.toSubUnit(),unconfirmedBalanceDisplayValue:L.toDisplay(),unconfirmedBalanceInCurrency:Y?.toDisplay({fixedDp:2,asNumber:!0}),unconfirmedBalanceCurrencyDisplayValue:Y?.toDisplay({fixedDp:2})}}}}))).reduce((y,g)=>g.status==="rejected"?y:{...y,...g.value},{})};var ye=async({accountIndex:r,xpub:e,isTestnet:t,walletType:n})=>{switch(n){case WalletType.Mnemonic:case WalletType.Ledger:case WalletType.Keystone:return {[NetworkVMType.BITCOIN]:getBech32AddressFromXPub(e,r,t?networks.testnet:networks.bitcoin)};case WalletType.LedgerLive:case WalletType.Seedless:{let o=Buffer.from(e,"hex");return {[NetworkVMType.BITCOIN]:getBtcAddressFromPubKey(o,t?networks.testnet:networks.bitcoin)}}default:throw rpcErrors.invalidParams(`Unsupported wallet type: ${n}`)}};var Qe=z$1.object({from:z$1.string(),to:z$1.string(),amount:z$1.number(),feeRate:z$1.number()}),fe=r=>Qe.safeParse(r);var ge=r=>{if(!r)return !1;let e="utxos"in r,t="locked"in r,n="unlockedUnstaked"in r;return e&&!n&&!t};var he=(r,e)=>r/e;var Te=async({request:r,network:e,approvalController:t,proxyApiUrl:n})=>{let{dappInfo:o,params:a}=r,{success:s,data:p,error:i}=fe(a);if(!s)return console.error("invalid params",i),{error:rpcErrors.invalidParams({message:"Transaction params are invalid",data:{cause:i}})};let v=(await N({addresses:[p.from],network:e,proxyApiUrl:n,withScripts:!0}))?.[p.from]?.[e.networkToken.symbol];if(!ge(v))return {error:rpcErrors.internal("Balance for the source account is not available")};let l=m({isTestnet:!!e.isTestnet,proxyApiUrl:n}),{to:b,from:R,amount:S,feeRate:E}=p,{inputs:y,outputs:g,fee:D}=createTransferTx(b,R,S,E,v.utxos,l.getNetwork());if(!y||!g)return {error:rpcErrors.internal("Unable to create transaction")};let F={title:"Approve Transaction",network:{chainId:e.chainId,name:e.chainName,logoUri:e.logoUri},details:[{title:"Transaction Details",items:[K("Website",new URL(o.url).hostname),U("From",R),U("To",b),z("Amount",BigInt(S),e.networkToken.decimals,e.networkToken.symbol)]}],networkFeeSelector:!0},$={type:RpcMethod.BITCOIN_SEND_TRANSACTION,account:R,data:{to:b,amount:S,fee:D,feeRate:E,gasLimit:he(D,E),inputs:y,outputs:g,balance:v}},h=await t.requestApproval({request:r,displayData:F,signingData:$});if("error"in h)return {error:h.error};let T;try{T=await qe(l,h);}catch(O){return {error:rpcErrors.internal({message:"Unable to get transaction hash",data:{cause:O}})}}return ze({provider:l,txHash:T,onTransactionConfirmed:t.onTransactionConfirmed,onTransactionReverted:t.onTransactionReverted}),{result:T}},qe=async(r,e)=>"txHash"in e?e.txHash:r.issueRawTx(e.signedData),ze=async({provider:r,txHash:e,onTransactionConfirmed:t,onTransactionReverted:n})=>{try{await r.waitForTx(e),t(e);}catch(o){console.error(o),n(e);}};var u,_,Pe=class{constructor({environment:e,approvalController:t}){P(this,u,void 0);P(this,_,void 0);let{proxyApiUrl:n}=te(e);x(this,_,t),x(this,u,n);}getProvider(e){return m({isTestnet:!!e.isTestnet,proxyApiUrl:c(this,u)})}getAddress({accountIndex:e,xpub:t,isTestnet:n,walletType:o}){return ye({accountIndex:e,xpub:t,isTestnet:n,walletType:o})}getBalances({addresses:e,currency:t,network:n,storage:o}){return N({addresses:e,currency:t,network:n,proxyApiUrl:c(this,u),storage:o})}getManifest(){let e=parseManifest(re);return e.success?e.data:void 0}getNetworkFee(e){return ne({isTestnet:!!e.isTestnet,proxyApiUrl:c(this,u)})}async getTransactionHistory({address:e,network:t}){return {transactions:await se({address:e,network:t,proxyApiUrl:c(this,u)})}}getTokens(e){return Promise.resolve([])}async onRpcRequest(e,t){switch(e.method){case RpcMethod.BITCOIN_SEND_TRANSACTION:return Te({request:e,network:t,approvalController:c(this,_),proxyApiUrl:c(this,u)});default:return {error:rpcErrors.methodNotSupported(`Method ${e.method} not supported`)}}}};u=new WeakMap,_=new WeakMap;
10
+ var xe=Object.defineProperty;var ve=(t,e,r)=>e in t?xe(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var Y=(t,e,r)=>(ve(t,typeof e!="symbol"?e+"":e,r),r),Z=(t,e,r)=>{if(!e.has(t))throw TypeError("Cannot "+r)};var c=(t,e,r)=>(Z(t,e,"read from private field"),r?r.call(t):e.get(t)),k=(t,e,r)=>{if(e.has(t))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(t):e.set(t,r);},P=(t,e,r,n)=>(Z(t,e,"write to private field"),n?n.call(t,r):e.set(t,r),r);var be={glacierApiUrl:"https://glacier-api.avax.network",proxyApiUrl:"https://proxy-api.avax.network"},Re={glacierApiUrl:"https://glacier-api-dev.avax.network",proxyApiUrl:"https://proxy-api-dev.avax.network"},ee=t=>{switch(t){case Environment.PRODUCTION:return be;case Environment.DEV:return Re}};var te={name:"Bitcoin",description:"",version:"0.0.1",sources:{module:{checksum:"",location:{npm:{filePath:"dist/bundle.js",packageName:"@avalabs/bitcoin-module",registry:"https://registry.npmjs.org"}}},provider:{checksum:"",location:{npm:{filePath:"dist/provider.js",packageName:"@avalabs/bitcoin-module",registry:"https://registry.npmjs.org"}}}},network:{chainIds:["bip122:000000000019d6689c085ae165831e93","bip122:000000000933ea01ad0ee984209779ba"],namespaces:["bip122"]},cointype:"0",permissions:{rpc:{dapps:!0,methods:["bitcoin_sendTransaction"]}},manifestVersion:"0.0"};var m=({isTestnet:t,proxyApiUrl:e})=>new BitcoinProvider(!t,void 0,`${e}/proxy/nownodes/${t?"btcbook-testnet":"btcbook"}`,`${e}/proxy/nownodes/${t?"btc-testnet":"btc"}`,process.env.GLACIER_API_KEY?{token:process.env.GLACIER_API_KEY}:{});async function re({isTestnet:t,proxyApiUrl:e}){let r=m({isTestnet:t,proxyApiUrl:e}),{high:n,low:o,medium:s}=await r.getFeeRates();return {low:{maxFeePerGas:BigInt(o)},medium:{maxFeePerGas:BigInt(s)},high:{maxFeePerGas:BigInt(n)},isFixedFee:!1}}var oe=(t,{address:e,network:r})=>{let{explorerUrl:n,networkToken:o}=r,s=t.addresses[0]??"";return {chainId:r.chainId.toString(),explorerLink:`${n}/tx/${t.hash}`,from:t.isSender?e:s,gasUsed:t.fee.toString(),hash:t.hash,isContractCall:!1,isIncoming:!t.isSender,isOutgoing:t.isSender,isSender:t.isSender,timestamp:t.receivedTime*1e3,to:t.isSender?s:e,tokens:[{amount:(Math.abs(t.amount)/10**o.decimals).toString(),decimal:o.decimals.toString(),name:o.name,symbol:o.symbol,type:TokenType.NATIVE}],txType:t.isSender?TransactionType.SEND:TransactionType.RECEIVE}};var se=async({address:t,network:e,proxyApiUrl:r})=>(await m({isTestnet:!!e.isTestnet,proxyApiUrl:r}).getTxHistory(t)).map(s=>oe(s,{address:t,network:e}));var V=async({operation:t,isSuccess:e,maxRetries:r=10,backoffPolicy:n=S.exponential()})=>{let o=0,s=0,a;for(;s<r;){s>0&&await we(o);try{let i=await t(s);if(e(i))return i}catch(i){a=i;}o=n(s),s++;}let p=a?`Max retry exceeded. ${a}`:"Max retry exceeded.";throw new Error(p)},S=class{static exponential(){return e=>Math.pow(2,e)*1e3}static constant(e){return r=>e*1e3}static constantMs(e){return r=>e}};function we(t){return new Promise(e=>setTimeout(e,t))}var j=t=>V({operation:e=>t(e>0),maxRetries:2,backoffPolicy:S.constant(1),isSuccess:e=>e?.status?.error_code!==429});function ae(t){let e,r=0;for(e=0;e<t.length;e++)r+=t.charCodeAt(e)*(e+1);return r}function q(t){let e,r=0;for(e=0;e<t.length;e++){let n=ae(t[e]??"");r=r+65027/n;}return (""+r).slice(0,16)}var W=t=>new Zodios(`${t}/proxy/coingecko`,[{method:"post",path:"/simple/price",parameters:[{name:"ids",type:"Query",schema:string()},{name:"vs_currencies",type:"Query",schema:string()},{name:"include_market_cap",type:"Query",schema:string().optional()},{name:"include_24hr_vol",type:"Query",schema:string().optional()},{name:"include_24hr_change",type:"Query",schema:string().optional()},{name:"include_last_updated_at",type:"Query",schema:string().optional()}],alias:"simplePrice",response:RawSimplePriceResponseSchema},{method:"post",path:"/simple/token_price/:id",parameters:[{name:"id",type:"Path",schema:string()},{name:"contract_addresses",type:"Query",schema:string().array()},{name:"vs_currencies",type:"Query",schema:string().array()},{name:"include_market_cap",type:"Query",schema:boolean().optional()},{name:"include_24hr_vol",type:"Query",schema:boolean().optional()},{name:"include_24hr_change",type:"Query",schema:boolean().optional()}],alias:"simplePriceByContractAddresses",response:SimplePriceResponseSchema}],{axiosConfig:{headers:{"Content-Type":"application/json"}}});var ie=getBasicCoingeckoHttp(),g,x,w=class{constructor({storage:e,proxyApiUrl:r}){k(this,g,void 0);k(this,x,void 0);Y(this,"transformSimplePriceResponse",(e,r=[VsCurrencyType.USD])=>{let n={};return Object.keys(e).forEach(o=>{let s=e[o];n[o]={},r.forEach(a=>{n[o]={[a]:{price:s?.[a],change24:s?.[`${a}_24h_change`],vol24:s?.[`${a}_24h_vol`],marketCap:s?.[`${a}_market_cap`]}};});}),n});P(this,g,e),P(this,x,r);}async getSimplePrice({coinIds:e=[],currencies:r=[VsCurrencyType.USD]}){let n,s=`getSimplePrice-${e?`${q(e)}-${r.toString()}`:`${r.toString()}`}`;if(n=c(this,g)?.get?.(s),n)return n;try{n=await j(a=>this.simplePrice({coinIds:e,currencies:r,marketCap:!0,vol24:!0,change24:!0,useCoingeckoProxy:a}));}catch{n=void 0;}return c(this,g)?.set?.(s,n),n}async getPricesByAddresses(e,r,n=VsCurrencyType.USD){let o,a=`getPricesWithMarketDataByAddresses-${`${q(e)}-${r}-${n}`}`;if(o=c(this,g)?.get?.(a),o)return o;try{o=await j(p=>this.fetchPricesByAddresses({assetPlatformId:r,tokenAddresses:e,currency:n,useCoingeckoProxy:p}));}catch{o=void 0;}return c(this,g)?.set?.(a,o),o}async fetchPricesByAddresses({assetPlatformId:e,tokenAddresses:r,currency:n=VsCurrencyType.USD,useCoingeckoProxy:o=!1}){return o?W(c(this,x)).simplePriceByContractAddresses(void 0,{params:{id:e},queries:{contract_addresses:r,vs_currencies:[n],include_market_cap:!0,include_24hr_vol:!0,include_24hr_change:!0}}):simpleTokenPrice(ie,{assetPlatformId:e,tokenAddresses:r,currencies:[n],marketCap:!0,vol24:!0,change24:!0})}async simplePrice({coinIds:e=[],currencies:r=[VsCurrencyType.USD],marketCap:n=!1,vol24:o=!1,change24:s=!1,lastUpdated:a=!1,useCoingeckoProxy:p=!1,shouldThrow:i=!0}){if(p){let M=await W(c(this,x)).simplePrice(void 0,{queries:{ids:e?.join(","),vs_currencies:r.join(","),include_market_cap:String(n),include_24hr_vol:String(o),include_24hr_change:String(s),include_last_updated_at:String(a)}});return this.transformSimplePriceResponse(M,r)}return simplePrice(ie,{coinIds:e,currencies:r,marketCap:n,vol24:o,change24:s,lastUpdated:a,shouldThrow:i})}};g=new WeakMap,x=new WeakMap;var Fe="https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/usd.min.json",Le="https://latest.currency-api.pages.dev/v1/currencies/usd.min.json",pe=object({date:string(),usd:record(number())});new Zodios(Fe,[{method:"get",path:"",alias:"getExchangeRates",response:pe}]);new Zodios(Le,[{method:"get",path:"",alias:"getExchangeRates",response:pe}]);var z=(t,e,r,n)=>({label:t,type:DetailItemType.CURRENCY,value:e,maxDecimals:r,symbol:n});var me=(t,e)=>({label:t,value:e,type:DetailItemType.LINK}),N=(t,e)=>({label:t,type:DetailItemType.ADDRESS,value:e});var le=(t,e,r)=>{let n=r?.[t]?.[e??""]??{};return {priceInCurrency:n.price??void 0,marketCap:n.marketCap??void 0,vol24:n.vol24??void 0,change24:n.change24??void 0}};var U=async({addresses:t,currency:e,network:r,withScripts:n,proxyApiUrl:o,storage:s})=>{let a=m({isTestnet:!!r.isTestnet,proxyApiUrl:o}),p=new w({proxyApiUrl:o,storage:s}),i=r.pricingProviders?.coingecko.nativeTokenId,v=typeof e=="string"&&typeof i=="string"?await p.getSimplePrice({coinIds:[i],currencies:[e]}):void 0,{priceInCurrency:l,change24:b,marketCap:R,vol24:I}=le(i??"",e,v);return (await Promise.allSettled(t.map(async y=>{let{balance:f,utxos:D,balanceUnconfirmed:F,utxosUnconfirmed:L}=await a.getUtxoBalance(y,n),h=new TokenUnit(f,r.networkToken.decimals,r.networkToken.symbol),T=l!==void 0?h.mul(l):void 0,$=h.toDisplay(),O=new TokenUnit(F,r.networkToken.decimals,r.networkToken.symbol),K=l!==void 0?O.mul(l):void 0,Pe=r.networkToken.symbol;return {[y]:{[Pe]:{...r.networkToken,utxos:D,utxosUnconfirmed:L,coingeckoId:i??"",type:TokenType.NATIVE,balance:h.toSubUnit(),balanceDisplayValue:$,balanceInCurrency:T?.toDisplay({fixedDp:2,asNumber:!0}),balanceCurrencyDisplayValue:T?.toDisplay({fixedDp:2}),priceInCurrency:l,marketCap:R,vol24:I,change24:b,unconfirmedBalance:O.toSubUnit(),unconfirmedBalanceDisplayValue:O.toDisplay(),unconfirmedBalanceInCurrency:K?.toDisplay({fixedDp:2,asNumber:!0}),unconfirmedBalanceCurrencyDisplayValue:K?.toDisplay({fixedDp:2})}}}}))).reduce((y,f)=>f.status==="rejected"?y:{...y,...f.value},{})};var ye=async({accountIndex:t,xpub:e,isTestnet:r,walletType:n})=>{switch(n){case WalletType.Mnemonic:case WalletType.Ledger:case WalletType.Keystone:return {[NetworkVMType.BITCOIN]:getBech32AddressFromXPub(e,t,r?networks.testnet:networks.bitcoin)};case WalletType.LedgerLive:case WalletType.Seedless:{let o=Buffer.from(e,"hex");return {[NetworkVMType.BITCOIN]:getBtcAddressFromPubKey(o,r?networks.testnet:networks.bitcoin)}}default:throw rpcErrors.invalidParams(`Unsupported wallet type: ${n}`)}};var qe=z$1.object({from:z$1.string(),to:z$1.string(),amount:z$1.number(),feeRate:z$1.number()}),ge=t=>qe.safeParse(t);var fe=t=>{if(!t)return !1;let e="utxos"in t,r="locked"in t,n="unlockedUnstaked"in t;return e&&!n&&!r};var he=(t,e)=>t/e;var Te=async({request:t,network:e,approvalController:r,proxyApiUrl:n})=>{let{dappInfo:o,params:s}=t,{success:a,data:p,error:i}=ge(s);if(!a)return console.error("invalid params",i),{error:rpcErrors.invalidParams({message:"Transaction params are invalid",data:{cause:i}})};let v=(await U({addresses:[p.from],network:e,proxyApiUrl:n,withScripts:!0}))?.[p.from]?.[e.networkToken.symbol];if(!fe(v))return {error:rpcErrors.internal("Balance for the source account is not available")};let l=m({isTestnet:!!e.isTestnet,proxyApiUrl:n}),{to:b,from:R,amount:I,feeRate:E}=p,{inputs:y,outputs:f,fee:D}=createTransferTx(b,R,I,E,v.utxos,l.getNetwork());if(!y||!f)return {error:rpcErrors.internal("Unable to create transaction")};let F={title:"Approve Transaction",network:{chainId:e.chainId,name:e.chainName,logoUri:e.logoUri},details:[{title:"Transaction Details",items:[me("Website",o),N("From",R),N("To",b),z("Amount",BigInt(I),e.networkToken.decimals,e.networkToken.symbol)]}],networkFeeSelector:!0},L={type:RpcMethod.BITCOIN_SEND_TRANSACTION,account:R,data:{to:b,amount:I,fee:D,feeRate:E,gasLimit:he(D,E),inputs:y,outputs:f,balance:v}},h=await r.requestApproval({request:t,displayData:F,signingData:L});if("error"in h)return {error:h.error};let T;try{T=await Xe(l,h);}catch($){return {error:rpcErrors.internal({message:"Unable to get transaction hash",data:{cause:$}})}}return ze({provider:l,txHash:T,onTransactionConfirmed:r.onTransactionConfirmed,onTransactionReverted:r.onTransactionReverted,requestId:t.requestId}),{result:T}},Xe=async(t,e)=>"txHash"in e?e.txHash:t.issueRawTx(e.signedData),ze=async({provider:t,txHash:e,onTransactionConfirmed:r,onTransactionReverted:n,requestId:o})=>{try{await t.waitForTx(e),r(e,o);}catch(s){console.error(s),n(e,o);}};var u,_,ke=class{constructor({environment:e,approvalController:r}){k(this,u,void 0);k(this,_,void 0);let{proxyApiUrl:n}=ee(e);P(this,_,r),P(this,u,n);}getProvider(e){return m({isTestnet:!!e.isTestnet,proxyApiUrl:c(this,u)})}getAddress({accountIndex:e,xpub:r,isTestnet:n,walletType:o}){return ye({accountIndex:e,xpub:r,isTestnet:n,walletType:o})}getBalances({addresses:e,currency:r,network:n,storage:o}){return U({addresses:e,currency:r,network:n,proxyApiUrl:c(this,u),storage:o})}getManifest(){let e=parseManifest(te);return e.success?e.data:void 0}getNetworkFee(e){return re({isTestnet:!!e.isTestnet,proxyApiUrl:c(this,u)})}async getTransactionHistory({address:e,network:r}){return {transactions:await se({address:e,network:r,proxyApiUrl:c(this,u)})}}getTokens(e){return Promise.resolve([])}async onRpcRequest(e,r){switch(e.method){case RpcMethod.BITCOIN_SEND_TRANSACTION:return Te({request:e,network:r,approvalController:c(this,_),proxyApiUrl:c(this,u)});default:return {error:rpcErrors.methodNotSupported(`Method ${e.method} not supported`)}}}};u=new WeakMap,_=new WeakMap;
11
11
 
12
- export { Pe as BitcoinModule, he as calculateGasLimit };
12
+ export { ke as BitcoinModule, he as calculateGasLimit };
13
13
  //# sourceMappingURL=out.js.map
14
14
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/module.ts","../src/env.ts","../manifest.json","../src/utils/get-provider.ts","../src/handlers/get-network-fee/get-network-fee.ts","../src/handlers/get-transaction-history/convert-btc-transaction.ts","../src/handlers/get-transaction-history/get-transaction-history.ts","../src/handlers/get-balances/get-balances.ts","../../../packages-internal/utils/src/services/token-service/token-service.ts","../../../packages-internal/utils/src/utils/retry.ts","../../../packages-internal/utils/src/utils/coingecko-retry.ts","../../../packages-internal/utils/src/utils/charsum.ts","../../../packages-internal/utils/src/utils/array-hash.ts","../../../packages-internal/utils/src/services/token-service/coingecko-proxy-client.ts","../../../packages-internal/utils/src/services/pricing-service/exchange-rates.ts","../../../packages-internal/utils/src/utils/detail-item.ts","../src/utils/extract-token-market-data.ts","../src/handlers/get-address/get-address.ts","../src/handlers/bitcoin-send-transaction/bitcoin-send-transaction.ts","../src/handlers/bitcoin-send-transaction/schema.ts","../src/utils/is-btc-balance.ts","../src/utils/calculate-gas-limit.ts"],"names":["RpcMethod","parseManifest","rpcErrors","Environment","prodEnv","devEnv","getEnv","environment","manifest_default","BitcoinProvider","getProvider","isTestnet","proxyApiUrl","getNetworkFee","provider","high","low","medium","TokenType","TransactionType","convertBtcTransaction","tx","address","network","explorerUrl","networkToken","txAddress","getTransactionHistory","TokenUnit","VsCurrencyType","getBasicCoingeckoHttp","simplePrice","simpleTokenPrice","retry","operation","isSuccess","maxRetries","backoffPolicy","RetryBackoffPolicy","backoffPeriodMillis","retries","lastError","delay","result","err","errorMessage","retryIndex","secondsToDelay","_","msToDelay","ms","r","coingeckoRetry","response","charsum","s","i","sum","arrayHash","array","cs","Zodios","RawSimplePriceResponseSchema","SimplePriceResponseSchema","boolean","string","coingeckoProxyClient","coingeckoBasicClient","_storage","_proxyApiUrl","TokenService","storage","__privateAdd","__publicField","data","currencies","formattedData","id","tokenData","currency","__privateSet","coinIds","cacheId","__privateGet","useCoingeckoProxy","tokenAddresses","assetPlatformId","marketCap","vol24","change24","lastUpdated","shouldThrow","rawData","number","object","record","CURRENCY_EXCHANGE_RATES_URL","CURRENCY_EXCHANGE_RATES_FALLBACK_URL","ExchangeRateSchema","exchangeRateApiClient","exchangeRateFallbackApiClient","DetailItemType","currencyItem","label","value","maxDecimals","symbol","textItem","alignment","addressItem","extractTokenMarketData","coinId","coinData","getBalances","addresses","withScripts","tokenService","coingeckoTokenId","marketData","priceInCurrency","balanceInSatoshis","utxos","unconfirmedBalanceInSatoshis","utxosUnconfirmed","balance","balanceInCurrency","balanceDisplayValue","unconfirmedBalance","unconfirmedBalanceInCurrency","acc","accountBalance","getBech32AddressFromXPub","getBtcAddressFromPubKey","networks","NetworkVMType","WalletType","getAddress","accountIndex","xpub","walletType","pubKeyBuffer","z","paramsSchema","parseRequestParams","params","isBtcBalance","hasUtxos","hasLocked","hasUnlockedUnstaked","createTransferTx","calculateGasLimit","fee","feeRate","bitcoinSendTransaction","request","approvalController","dappInfo","rawParams","success","parseError","btcBalance","to","from","amount","inputs","outputs","displayData","signingData","txHash","getTxHash","error","waitForTransactionReceipt","onTransactionConfirmed","onTransactionReverted","_approvalController","BitcoinModule"],"mappings":"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","sourcesContent":["import type {\n Module,\n Manifest,\n NetworkFees,\n GetTransactionHistory,\n RpcRequest,\n Network,\n Environment,\n GetBalancesParams,\n GetAddressParams,\n GetAddressResponse,\n ApprovalController,\n} from '@avalabs/vm-module-types';\nimport { RpcMethod, parseManifest } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { getEnv } from './env';\n\nimport ManifestJson from '../manifest.json';\nimport { getNetworkFee } from './handlers/get-network-fee/get-network-fee';\nimport { getTransactionHistory } from './handlers/get-transaction-history/get-transaction-history';\nimport { getBalances } from './handlers/get-balances/get-balances';\nimport { getAddress } from './handlers/get-address/get-address';\nimport { bitcoinSendTransaction } from './handlers/bitcoin-send-transaction/bitcoin-send-transaction';\nimport type { BitcoinProvider } from '@avalabs/core-wallets-sdk';\nimport { getProvider } from './utils/get-provider';\n\nexport class BitcoinModule implements Module {\n #proxyApiUrl: string;\n #approvalController: ApprovalController;\n\n constructor({\n environment,\n approvalController,\n }: {\n environment: Environment;\n approvalController: ApprovalController;\n }) {\n const { proxyApiUrl } = getEnv(environment);\n\n this.#approvalController = approvalController;\n this.#proxyApiUrl = proxyApiUrl;\n }\n\n getProvider(network: Network): BitcoinProvider {\n return getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl: this.#proxyApiUrl,\n });\n }\n\n getAddress({ accountIndex, xpub, isTestnet, walletType }: GetAddressParams): Promise<GetAddressResponse> {\n return getAddress({ accountIndex, xpub, isTestnet, walletType });\n }\n\n getBalances({ addresses, currency, network, storage }: GetBalancesParams) {\n return getBalances({\n addresses,\n currency,\n network,\n proxyApiUrl: this.#proxyApiUrl,\n storage,\n });\n }\n\n getManifest(): Manifest | undefined {\n const result = parseManifest(ManifestJson);\n return result.success ? result.data : undefined;\n }\n\n getNetworkFee(network: Network): Promise<NetworkFees> {\n return getNetworkFee({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl: this.#proxyApiUrl,\n });\n }\n\n async getTransactionHistory({ address, network }: GetTransactionHistory) {\n return {\n transactions: await getTransactionHistory({\n address,\n network,\n proxyApiUrl: this.#proxyApiUrl,\n }),\n };\n }\n\n getTokens(_: Network) {\n return Promise.resolve([]);\n }\n\n async onRpcRequest(request: RpcRequest, network: Network) {\n switch (request.method) {\n case RpcMethod.BITCOIN_SEND_TRANSACTION:\n return bitcoinSendTransaction({\n request,\n network,\n approvalController: this.#approvalController,\n proxyApiUrl: this.#proxyApiUrl,\n });\n default:\n return { error: rpcErrors.methodNotSupported(`Method ${request.method} not supported`) };\n }\n }\n}\n","import { Environment } from '@avalabs/vm-module-types';\n\ntype Env = {\n glacierApiUrl: string;\n proxyApiUrl: string;\n};\n\nexport const prodEnv: Env = {\n glacierApiUrl: 'https://glacier-api.avax.network',\n proxyApiUrl: 'https://proxy-api.avax.network',\n};\n\nexport const devEnv: Env = {\n glacierApiUrl: 'https://glacier-api-dev.avax.network',\n proxyApiUrl: 'https://proxy-api-dev.avax.network',\n};\n\nexport const getEnv = (environment: Environment): Env => {\n switch (environment) {\n case Environment.PRODUCTION:\n return prodEnv;\n case Environment.DEV:\n return devEnv;\n }\n};\n","{\n \"name\": \"Bitcoin\",\n \"description\": \"\",\n \"version\": \"0.0.1\",\n \"sources\": {\n \"module\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/bundle.js\",\n \"packageName\": \"@avalabs/bitcoin-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n },\n \"provider\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/provider.js\",\n \"packageName\": \"@avalabs/bitcoin-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n }\n },\n \"network\": {\n \"chainIds\": [\"bip122:000000000019d6689c085ae165831e93\", \"bip122:000000000933ea01ad0ee984209779ba\"],\n \"namespaces\": [\"bip122\"]\n },\n \"cointype\": \"0\",\n \"permissions\": {\n \"rpc\": {\n \"dapps\": true,\n \"methods\": [\"bitcoin_sendTransaction\"]\n }\n },\n \"manifestVersion\": \"0.0\"\n}\n","import { BitcoinProvider } from '@avalabs/core-wallets-sdk';\n\ntype ProviderParams = {\n isTestnet: boolean;\n proxyApiUrl: string;\n};\n\nexport const getProvider = ({ isTestnet, proxyApiUrl }: ProviderParams): BitcoinProvider =>\n new BitcoinProvider(\n !isTestnet,\n undefined,\n `${proxyApiUrl}/proxy/nownodes/${isTestnet ? 'btcbook-testnet' : 'btcbook'}`,\n `${proxyApiUrl}/proxy/nownodes/${isTestnet ? 'btc-testnet' : 'btc'}`,\n\n // The Glacier API key is only needed in development to bypass rate limits.\n // It should never be used in production.\n process.env.GLACIER_API_KEY ? { token: process.env.GLACIER_API_KEY } : {},\n );\n","import type { NetworkFees } from '@avalabs/vm-module-types';\n\nimport { getProvider } from '../../utils/get-provider';\n\n/**\n * Returns {@link NetworkFees} based on `estimatesmartfee` RPC call\n */\nexport async function getNetworkFee({\n isTestnet,\n proxyApiUrl,\n}: {\n isTestnet: boolean;\n proxyApiUrl: string;\n}): Promise<NetworkFees> {\n const provider = getProvider({\n isTestnet,\n proxyApiUrl,\n });\n\n const { high, low, medium } = await provider.getFeeRates();\n\n return {\n low: {\n maxFeePerGas: BigInt(low),\n },\n medium: {\n maxFeePerGas: BigInt(medium),\n },\n high: {\n maxFeePerGas: BigInt(high),\n },\n isFixedFee: false,\n };\n}\n","import { TokenType, TransactionType, type Network, type Transaction } from '@avalabs/vm-module-types';\nimport type { BitcoinHistoryTx } from '@avalabs/core-wallets-sdk';\n\ntype ConverterOptions = {\n address: string;\n network: Network;\n};\n\nexport const convertBtcTransaction = (tx: BitcoinHistoryTx, { address, network }: ConverterOptions): Transaction => {\n const { explorerUrl, networkToken } = network;\n const txAddress = tx.addresses[0] ?? '';\n\n return {\n chainId: network.chainId.toString(),\n explorerLink: `${explorerUrl}/tx/${tx.hash}`,\n from: tx.isSender ? address : txAddress,\n gasUsed: tx.fee.toString(),\n hash: tx.hash,\n isContractCall: false,\n isIncoming: !tx.isSender,\n isOutgoing: tx.isSender,\n isSender: tx.isSender,\n timestamp: tx.receivedTime * 1000,\n to: tx.isSender ? txAddress : address,\n tokens: [\n {\n amount: (Math.abs(tx.amount) / 10 ** networkToken.decimals).toString(),\n decimal: networkToken.decimals.toString(),\n name: networkToken.name,\n symbol: networkToken.symbol,\n type: TokenType.NATIVE,\n },\n ],\n txType: tx.isSender ? TransactionType.SEND : TransactionType.RECEIVE,\n };\n};\n","import type { Network } from '@avalabs/vm-module-types';\n\nimport { getProvider } from '../../utils/get-provider';\n\nimport { convertBtcTransaction } from './convert-btc-transaction';\n\ntype GetBtcTransactionHistoryOptions = {\n network: Network;\n address: string;\n proxyApiUrl: string;\n};\n\nexport const getTransactionHistory = async ({ address, network, proxyApiUrl }: GetBtcTransactionHistoryOptions) => {\n const provider = getProvider({ isTestnet: Boolean(network.isTestnet), proxyApiUrl });\n const rawHistory = await provider.getTxHistory(address);\n\n return rawHistory.map((tx) =>\n convertBtcTransaction(tx, {\n address,\n network,\n }),\n );\n};\n","import { type GetBalancesParams, TokenType, type TokenWithBalanceBTC } from '@avalabs/vm-module-types';\nimport { TokenUnit } from '@avalabs/core-utils-sdk';\nimport type { VsCurrencyType } from '@avalabs/core-coingecko-sdk';\n\nimport { TokenService } from '@internal/utils';\n\nimport { getProvider } from '../../utils/get-provider';\nimport { extractTokenMarketData } from '../../utils/extract-token-market-data';\n\ntype GetBtcBalancesResponse = Record<string, Record<string, TokenWithBalanceBTC>>;\n\ntype GetBTCBalancesParams = Omit<GetBalancesParams, 'currency'> & {\n proxyApiUrl: string;\n withScripts?: boolean;\n currency?: string;\n};\n\nexport const getBalances = async ({\n addresses,\n currency,\n network,\n withScripts,\n proxyApiUrl,\n storage,\n}: GetBTCBalancesParams): Promise<GetBtcBalancesResponse> => {\n const provider = getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl,\n });\n\n const tokenService = new TokenService({ proxyApiUrl, storage });\n const coingeckoTokenId = network.pricingProviders?.coingecko.nativeTokenId;\n const withPrices = typeof currency === 'string' && typeof coingeckoTokenId === 'string';\n const marketData = withPrices\n ? await tokenService.getSimplePrice({\n coinIds: [coingeckoTokenId],\n currencies: [currency] as VsCurrencyType[],\n })\n : undefined;\n const { priceInCurrency, change24, marketCap, vol24 } = extractTokenMarketData(\n coingeckoTokenId ?? '',\n currency,\n marketData,\n );\n\n const balances = await Promise.allSettled(\n addresses.map(async (address) => {\n const {\n balance: balanceInSatoshis,\n utxos,\n balanceUnconfirmed: unconfirmedBalanceInSatoshis,\n utxosUnconfirmed,\n } = await provider.getUtxoBalance(address, withScripts);\n\n const balance = new TokenUnit(balanceInSatoshis, network.networkToken.decimals, network.networkToken.symbol);\n const balanceInCurrency = priceInCurrency !== undefined ? balance.mul(priceInCurrency) : undefined;\n const balanceDisplayValue = balance.toDisplay();\n\n const unconfirmedBalance = new TokenUnit(\n unconfirmedBalanceInSatoshis,\n network.networkToken.decimals,\n network.networkToken.symbol,\n );\n const unconfirmedBalanceInCurrency =\n priceInCurrency !== undefined ? unconfirmedBalance.mul(priceInCurrency) : undefined;\n\n const symbol = network.networkToken.symbol;\n\n return {\n [address]: {\n [symbol]: {\n ...network.networkToken,\n utxos,\n utxosUnconfirmed,\n coingeckoId: coingeckoTokenId ?? '',\n type: TokenType.NATIVE,\n balance: balance.toSubUnit(),\n balanceDisplayValue,\n balanceInCurrency: balanceInCurrency?.toDisplay({ fixedDp: 2, asNumber: true }),\n balanceCurrencyDisplayValue: balanceInCurrency?.toDisplay({ fixedDp: 2 }),\n priceInCurrency,\n marketCap,\n vol24,\n change24,\n unconfirmedBalance: unconfirmedBalance.toSubUnit(),\n unconfirmedBalanceDisplayValue: unconfirmedBalance.toDisplay(),\n unconfirmedBalanceInCurrency: unconfirmedBalanceInCurrency?.toDisplay({\n fixedDp: 2,\n asNumber: true,\n }),\n unconfirmedBalanceCurrencyDisplayValue: unconfirmedBalanceInCurrency?.toDisplay({ fixedDp: 2 }),\n },\n },\n };\n }),\n );\n\n return balances.reduce((acc, accountBalance) => {\n if (accountBalance.status === 'rejected') {\n return acc;\n }\n\n return {\n ...acc,\n ...accountBalance.value,\n };\n }, {});\n};\n","import {\n VsCurrencyType,\n getBasicCoingeckoHttp,\n simplePrice,\n simpleTokenPrice,\n type SimplePriceParams,\n} from '@avalabs/core-coingecko-sdk';\nimport type { Storage, RawSimplePriceResponse, SimplePriceResponse } from '@avalabs/vm-module-types';\nimport { coingeckoRetry } from '../../utils/coingecko-retry';\nimport { arrayHash } from '../../utils/array-hash';\nimport { coingeckoProxyClient } from './coingecko-proxy-client';\n\nconst coingeckoBasicClient = getBasicCoingeckoHttp();\n\nexport class TokenService {\n #storage?: Storage;\n #proxyApiUrl: string;\n\n constructor({ storage, proxyApiUrl }: { proxyApiUrl: string; storage?: Storage }) {\n this.#storage = storage;\n this.#proxyApiUrl = proxyApiUrl;\n }\n\n /**\n * Get token price with market data first on coingecko (free tier) directly,\n * if we get 429 error, retry it on coingecko proxy (paid service)\n * @returns token price with market data\n */\n async getSimplePrice({\n coinIds = [],\n currencies = [VsCurrencyType.USD],\n }: SimplePriceParams): Promise<SimplePriceResponse | undefined> {\n let data: SimplePriceResponse | undefined;\n\n const key = coinIds ? `${arrayHash(coinIds)}-${currencies.toString()}` : `${currencies.toString()}`;\n\n const cacheId = `getSimplePrice-${key}`;\n\n data = this.#storage?.get?.<SimplePriceResponse>(cacheId);\n\n if (data) return data;\n\n try {\n data = await coingeckoRetry((useCoingeckoProxy) =>\n this.simplePrice({\n coinIds,\n currencies,\n marketCap: true,\n vol24: true,\n change24: true,\n useCoingeckoProxy,\n }),\n );\n } catch {\n data = undefined;\n }\n this.#storage?.set?.(cacheId, data);\n return data;\n }\n\n /**\n * Get token price with market data for a list of addresses\n * @param tokenAddresses the token addresses\n * @param assetPlatformId The platform id for all the tokens in the list\n * @param currency the currency to be used\n * @returns a list of token price with market data\n */\n async getPricesByAddresses(\n tokenAddresses: string[],\n assetPlatformId: string,\n currency: VsCurrencyType = VsCurrencyType.USD,\n ): Promise<SimplePriceResponse | undefined> {\n let data: SimplePriceResponse | undefined;\n\n const key = `${arrayHash(tokenAddresses)}-${assetPlatformId}-${currency}`;\n\n const cacheId = `getPricesWithMarketDataByAddresses-${key}`;\n data = this.#storage?.get?.<SimplePriceResponse>(cacheId);\n\n if (data) return data;\n\n try {\n data = await coingeckoRetry((useCoingeckoProxy) =>\n this.fetchPricesByAddresses({\n assetPlatformId,\n tokenAddresses,\n currency,\n useCoingeckoProxy,\n }),\n );\n } catch {\n data = undefined;\n }\n this.#storage?.set?.(cacheId, data);\n return data;\n }\n\n private async fetchPricesByAddresses({\n assetPlatformId,\n tokenAddresses,\n currency = VsCurrencyType.USD,\n useCoingeckoProxy = false,\n }: {\n assetPlatformId: string;\n tokenAddresses: string[];\n currency: VsCurrencyType;\n useCoingeckoProxy?: boolean;\n }): Promise<SimplePriceResponse> {\n if (useCoingeckoProxy) {\n return coingeckoProxyClient(this.#proxyApiUrl).simplePriceByContractAddresses(undefined, {\n params: {\n id: assetPlatformId,\n },\n queries: {\n contract_addresses: tokenAddresses,\n vs_currencies: [currency],\n include_market_cap: true,\n include_24hr_vol: true,\n include_24hr_change: true,\n },\n });\n }\n\n return simpleTokenPrice(coingeckoBasicClient, {\n assetPlatformId,\n tokenAddresses,\n currencies: [currency],\n marketCap: true,\n vol24: true,\n change24: true,\n });\n }\n\n private async simplePrice({\n coinIds = [],\n currencies = [VsCurrencyType.USD],\n marketCap = false,\n vol24 = false,\n change24 = false,\n lastUpdated = false,\n useCoingeckoProxy = false,\n shouldThrow = true,\n }: SimplePriceParams & { useCoingeckoProxy?: boolean }): Promise<SimplePriceResponse> {\n if (useCoingeckoProxy) {\n const rawData = await coingeckoProxyClient(this.#proxyApiUrl).simplePrice(undefined, {\n queries: {\n ids: coinIds?.join(','),\n vs_currencies: currencies.join(','),\n include_market_cap: String(marketCap),\n include_24hr_vol: String(vol24),\n include_24hr_change: String(change24),\n include_last_updated_at: String(lastUpdated),\n },\n });\n return this.transformSimplePriceResponse(rawData, currencies);\n }\n return simplePrice(coingeckoBasicClient, {\n coinIds,\n currencies,\n marketCap,\n vol24,\n change24,\n lastUpdated,\n shouldThrow,\n });\n }\n\n private transformSimplePriceResponse = (\n data: RawSimplePriceResponse,\n currencies = [VsCurrencyType.USD],\n ): SimplePriceResponse => {\n const formattedData: SimplePriceResponse = {};\n Object.keys(data).forEach((id) => {\n const tokenData = data[id];\n formattedData[id] = {};\n currencies.forEach((currency: VsCurrencyType) => {\n formattedData[id] = {\n [currency]: {\n price: tokenData?.[currency],\n change24: tokenData?.[`${currency}_24h_change`],\n vol24: tokenData?.[`${currency}_24h_vol`],\n marketCap: tokenData?.[`${currency}_market_cap`],\n },\n };\n });\n });\n return formattedData;\n };\n}\n","const DEFAULT_MAX_RETRIES = 10;\n\ntype RetryParams<T> = {\n operation: (retryIndex: number) => Promise<T>;\n isSuccess: (result: T) => boolean;\n maxRetries?: number;\n backoffPolicy?: RetryBackoffPolicyInterface;\n};\n/*\n * Retries an operation with defined backoff policy.\n *\n * @param operation - The operation to retry.\n * @param isSuccess - The predicate to check if the operation succeeded.\n * @param maxRetries - The maximum number of retries.\n * @param backoffPolicy - Function to generate delay time based on current retry count.\n *\n * @returns The result of the operation.\n * @throws An error if the operation fails after the maximum number of retries.\n *\n * @example\n * const result = await retry(\n * async () => {\n * const response = await fetch('https://example.com')\n * return response.json()\n * },\n * result => result.status === 200\n * )\n */\nexport const retry = async <T>({\n operation,\n isSuccess,\n maxRetries = DEFAULT_MAX_RETRIES,\n backoffPolicy = RetryBackoffPolicy.exponential(),\n}: RetryParams<T>): Promise<T> => {\n let backoffPeriodMillis = 0;\n let retries = 0;\n let lastError: unknown;\n\n while (retries < maxRetries) {\n if (retries > 0) {\n await delay(backoffPeriodMillis);\n }\n\n try {\n const result = await operation(retries);\n\n if (isSuccess(result)) {\n return result;\n }\n } catch (err) {\n // when the operation throws an error, we still retry\n lastError = err;\n }\n\n backoffPeriodMillis = backoffPolicy(retries);\n retries++;\n }\n\n const errorMessage = lastError ? `Max retry exceeded. ${lastError}` : 'Max retry exceeded.';\n\n throw new Error(errorMessage);\n};\n\ntype RetryBackoffPolicyInterface = (retryIndex: number) => number;\n\nexport class RetryBackoffPolicy {\n static exponential(): RetryBackoffPolicyInterface {\n return (retryIndex: number): number => {\n return Math.pow(2, retryIndex) * 1000;\n };\n }\n\n static constant(secondsToDelay: number): RetryBackoffPolicyInterface {\n return (_: number): number => {\n return secondsToDelay * 1000;\n };\n }\n\n static constantMs(msToDelay: number): RetryBackoffPolicyInterface {\n return (_: number): number => {\n return msToDelay;\n };\n }\n}\n\nfunction delay(ms: number) {\n return new Promise((r) => setTimeout(r, ms));\n}\n","import { RetryBackoffPolicy, retry } from './retry';\n\ntype Error = {\n status: {\n error_code: number;\n error_message: string;\n };\n};\n\nexport const coingeckoRetry = <T>(\n operation: (useCoingeckoProxy: boolean) => Promise<T | Error>,\n): Promise<T | undefined> => {\n return retry({\n operation: (retryIndex: number) => operation(retryIndex > 0),\n maxRetries: 2,\n backoffPolicy: RetryBackoffPolicy.constant(1),\n isSuccess: (response: T | Error) => {\n const errorStatus = (response as Error)?.status;\n return errorStatus?.error_code !== 429;\n },\n }) as Promise<T | undefined>;\n};\n","export function charsum(s: string): number {\n let i,\n sum = 0;\n for (i = 0; i < s.length; i++) {\n sum += s.charCodeAt(i) * (i + 1);\n }\n return sum;\n}\n","import { charsum } from './charsum';\n\n// from https://stackoverflow.com/a/25105589\nexport function arrayHash(array: string[]): string {\n let i,\n sum = 0;\n for (i = 0; i < array.length; i++) {\n const cs = charsum(array[i] ?? '');\n sum = sum + 65027 / cs;\n }\n return ('' + sum).slice(0, 16);\n}\n","import { Zodios } from '@zodios/core';\nimport { RawSimplePriceResponseSchema, SimplePriceResponseSchema } from '@avalabs/vm-module-types';\nimport { boolean, string } from 'zod';\n\nexport const coingeckoProxyClient = (proxyApiUrl: string) =>\n new Zodios(\n `${proxyApiUrl}/proxy/coingecko`,\n [\n {\n method: 'post',\n path: '/simple/price',\n parameters: [\n { name: 'ids', type: 'Query', schema: string() },\n { name: 'vs_currencies', type: 'Query', schema: string() },\n {\n name: 'include_market_cap',\n type: 'Query',\n schema: string().optional(),\n },\n {\n name: 'include_24hr_vol',\n type: 'Query',\n schema: string().optional(),\n },\n {\n name: 'include_24hr_change',\n type: 'Query',\n schema: string().optional(),\n },\n {\n name: 'include_last_updated_at',\n type: 'Query',\n schema: string().optional(),\n },\n ],\n alias: 'simplePrice',\n response: RawSimplePriceResponseSchema,\n },\n {\n method: 'post',\n path: '/simple/token_price/:id',\n parameters: [\n { name: 'id', type: 'Path', schema: string() },\n { name: 'contract_addresses', type: 'Query', schema: string().array() },\n { name: 'vs_currencies', type: 'Query', schema: string().array() },\n {\n name: 'include_market_cap',\n type: 'Query',\n schema: boolean().optional(),\n },\n {\n name: 'include_24hr_vol',\n type: 'Query',\n schema: boolean().optional(),\n },\n {\n name: 'include_24hr_change',\n type: 'Query',\n schema: boolean().optional(),\n },\n ],\n alias: 'simplePriceByContractAddresses',\n response: SimplePriceResponseSchema,\n },\n ],\n {\n axiosConfig: {\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n },\n );\n","import { Zodios } from '@zodios/core';\nimport z, { number, object, record, string } from 'zod';\n\nconst CURRENCY_EXCHANGE_RATES_URL =\n 'https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/usd.min.json';\n\nconst CURRENCY_EXCHANGE_RATES_FALLBACK_URL = 'https://latest.currency-api.pages.dev/v1/currencies/usd.min.json';\n\nconst ExchangeRateSchema = object({\n date: string(),\n usd: record(number()),\n});\n\ntype ExchangeRate = z.infer<typeof ExchangeRateSchema>;\n\nconst exchangeRateApiClient = new Zodios(CURRENCY_EXCHANGE_RATES_URL, [\n {\n method: 'get',\n path: '',\n alias: 'getExchangeRates',\n response: ExchangeRateSchema,\n },\n]);\n\nconst exchangeRateFallbackApiClient = new Zodios(CURRENCY_EXCHANGE_RATES_FALLBACK_URL, [\n {\n method: 'get',\n path: '',\n alias: 'getExchangeRates',\n response: ExchangeRateSchema,\n },\n]);\n\nexport const getExchangeRates = async (): Promise<ExchangeRate> => {\n try {\n return await exchangeRateApiClient.getExchangeRates();\n } catch {\n return await exchangeRateFallbackApiClient.getExchangeRates();\n }\n};\n","import {\n type AddressItem,\n type CurrencyItem,\n type NodeIDItem,\n type TextItem,\n type DataItem,\n type DateItem,\n DetailItemType,\n} from '@avalabs/vm-module-types';\n\nexport const currencyItem = (label: string, value: bigint, maxDecimals: number, symbol: string): CurrencyItem => ({\n label,\n type: DetailItemType.CURRENCY,\n value,\n maxDecimals,\n symbol,\n});\n\nexport const textItem = (\n label: string,\n value: string,\n alignment: 'horizontal' | 'vertical' = 'horizontal',\n): TextItem => ({\n label,\n alignment,\n type: DetailItemType.TEXT,\n value,\n});\n\nexport const addressItem = (label: string, value: string): AddressItem => ({\n label,\n type: DetailItemType.ADDRESS,\n value,\n});\n\nexport const nodeIDItem = (label: string, value: string): NodeIDItem => ({\n label,\n type: DetailItemType.NODE_ID,\n value,\n});\n\nexport const dataItem = (label: string, value: string): DataItem => ({\n label,\n type: DetailItemType.DATA,\n value,\n});\n\nexport const dateItem = (label: string, value: string): DateItem => ({\n label,\n type: DetailItemType.DATE,\n value,\n});\n","import type { SimplePriceResponse, TokenMarketData } from '@avalabs/vm-module-types';\n\nexport const extractTokenMarketData = (\n coinId: string,\n currency?: string,\n data?: SimplePriceResponse,\n): TokenMarketData => {\n const coinData = data?.[coinId]?.[currency ?? ''] ?? {};\n\n return {\n priceInCurrency: coinData.price ?? undefined,\n marketCap: coinData.marketCap ?? undefined,\n vol24: coinData.vol24 ?? undefined,\n change24: coinData.change24 ?? undefined,\n };\n};\n","import type { GetAddressParams, GetAddressResponse } from '@avalabs/vm-module-types';\nimport { getBech32AddressFromXPub, getBtcAddressFromPubKey } from '@avalabs/core-wallets-sdk';\nimport { networks } from 'bitcoinjs-lib';\nimport { NetworkVMType, WalletType } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\n\ntype GetAddress = Omit<GetAddressParams, 'xpubXP'>;\n\nexport const getAddress = async ({\n accountIndex,\n xpub,\n isTestnet,\n walletType,\n}: GetAddress): Promise<GetAddressResponse> => {\n switch (walletType) {\n case WalletType.Mnemonic:\n case WalletType.Ledger:\n case WalletType.Keystone: {\n return {\n [NetworkVMType.BITCOIN]: getBech32AddressFromXPub(\n xpub,\n accountIndex,\n isTestnet ? networks.testnet : networks.bitcoin,\n ),\n };\n }\n case WalletType.LedgerLive:\n case WalletType.Seedless: {\n const pubKeyBuffer = Buffer.from(xpub, 'hex');\n return {\n [NetworkVMType.BITCOIN]: getBtcAddressFromPubKey(pubKeyBuffer, isTestnet ? networks.testnet : networks.bitcoin),\n };\n }\n default:\n throw rpcErrors.invalidParams(`Unsupported wallet type: ${walletType}`);\n }\n};\n","import {\n RpcMethod,\n type ApprovalController,\n type DisplayData,\n type Hex,\n type Network,\n type RpcRequest,\n type SigningData,\n type SigningResult,\n} from '@avalabs/vm-module-types';\nimport { parseRequestParams } from './schema';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { getProvider } from '../../utils/get-provider';\nimport { getBalances } from '../get-balances/get-balances';\nimport { isBtcBalance } from '../../utils/is-btc-balance';\nimport { BitcoinProvider, createTransferTx, type BitcoinInputUTXO } from '@avalabs/core-wallets-sdk';\nimport { calculateGasLimit } from '../../utils/calculate-gas-limit';\nimport { addressItem, currencyItem, textItem } from '@internal/utils';\n\ntype BitcoinSendTransactionParams = {\n request: RpcRequest;\n network: Network;\n approvalController: ApprovalController;\n proxyApiUrl: string;\n};\n\nexport const bitcoinSendTransaction = async ({\n request,\n network,\n approvalController,\n proxyApiUrl,\n}: BitcoinSendTransactionParams) => {\n const { dappInfo, params: rawParams } = request;\n\n const { success, data: params, error: parseError } = parseRequestParams(rawParams);\n\n if (!success) {\n console.error('invalid params', parseError);\n return {\n error: rpcErrors.invalidParams({ message: 'Transaction params are invalid', data: { cause: parseError } }),\n };\n }\n\n const balances = await getBalances({ addresses: [params.from], network, proxyApiUrl, withScripts: true });\n const btcBalance = balances?.[params.from]?.[network.networkToken.symbol];\n\n if (!isBtcBalance(btcBalance)) {\n return {\n error: rpcErrors.internal('Balance for the source account is not available'),\n };\n }\n\n const provider = getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl,\n });\n\n const { to, from, amount, feeRate } = params;\n\n const { inputs, outputs, fee } = createTransferTx(\n to,\n from,\n amount,\n feeRate,\n btcBalance.utxos as BitcoinInputUTXO[], // we asked for scripts in getBalances() call\n provider.getNetwork(),\n );\n\n if (!inputs || !outputs) {\n return {\n error: rpcErrors.internal('Unable to create transaction'),\n };\n }\n\n const displayData: DisplayData = {\n title: 'Approve Transaction',\n network: {\n chainId: network.chainId,\n name: network.chainName,\n logoUri: network.logoUri,\n },\n details: [\n {\n title: 'Transaction Details',\n items: [\n textItem('Website', new URL(dappInfo.url).hostname),\n addressItem('From', from),\n addressItem('To', to),\n currencyItem('Amount', BigInt(amount), network.networkToken.decimals, network.networkToken.symbol),\n ],\n },\n ],\n networkFeeSelector: true,\n };\n\n const signingData: SigningData = {\n type: RpcMethod.BITCOIN_SEND_TRANSACTION,\n account: from,\n data: {\n to,\n amount,\n fee,\n feeRate,\n gasLimit: calculateGasLimit(fee, feeRate),\n inputs,\n outputs,\n balance: btcBalance,\n },\n };\n\n const response = await approvalController.requestApproval({ request, displayData, signingData });\n\n if ('error' in response) {\n return {\n error: response.error,\n };\n }\n\n let txHash;\n\n try {\n txHash = await getTxHash(provider, response);\n } catch (error) {\n return {\n error: rpcErrors.internal({ message: 'Unable to get transaction hash', data: { cause: error } }),\n };\n }\n\n waitForTransactionReceipt({\n provider,\n txHash: txHash as Hex,\n onTransactionConfirmed: approvalController.onTransactionConfirmed,\n onTransactionReverted: approvalController.onTransactionReverted,\n });\n\n return {\n result: txHash,\n };\n};\n\nconst getTxHash = async (provider: BitcoinProvider, response: SigningResult) => {\n if ('txHash' in response) {\n return response.txHash;\n }\n\n return provider.issueRawTx(response.signedData);\n};\n\nconst waitForTransactionReceipt = async ({\n provider,\n txHash,\n onTransactionConfirmed,\n onTransactionReverted,\n}: {\n provider: BitcoinProvider;\n txHash: Hex;\n onTransactionConfirmed: (txHash: Hex) => void;\n onTransactionReverted: (txHash: Hex) => void;\n}) => {\n try {\n await provider.waitForTx(txHash);\n onTransactionConfirmed(txHash);\n } catch (err) {\n console.error(err);\n onTransactionReverted(txHash);\n }\n};\n","import { z } from 'zod';\n\nconst paramsSchema = z.object({\n from: z.string(),\n to: z.string(),\n amount: z.number(),\n feeRate: z.number(),\n});\n\nexport const parseRequestParams = (params: unknown) => {\n return paramsSchema.safeParse(params);\n};\n\nexport type BitcoinSendTransactionParams = z.infer<typeof paramsSchema>;\n","import type { TokenWithBalance, TokenWithBalanceBTC } from '@avalabs/vm-module-types';\n\nexport const isBtcBalance = (balance?: TokenWithBalance): balance is TokenWithBalanceBTC => {\n if (!balance) {\n return false;\n }\n\n const hasUtxos = 'utxos' in balance; // BTC, P-Chain or X-Chain\n const hasLocked = 'locked' in balance; // X-Chain only\n const hasUnlockedUnstaked = 'unlockedUnstaked' in balance; // P-Chain only\n\n return hasUtxos && !hasUnlockedUnstaked && !hasLocked;\n};\n","// The transaction's byte size is for BTC as gasLimit is for EVM.\n// Bitcoin's formula for fee is `transactionByteLength * feeRate`.\n// Since we know the `fee` and the `feeRate`, we can get the transaction's\n// byte length by division.\nexport const calculateGasLimit = (fee: number, feeRate: number): number => {\n return fee / feeRate;\n};\n"]}
1
+ {"version":3,"sources":["../src/module.ts","../src/env.ts","../manifest.json","../src/utils/get-provider.ts","../src/handlers/get-network-fee/get-network-fee.ts","../src/handlers/get-transaction-history/convert-btc-transaction.ts","../src/handlers/get-transaction-history/get-transaction-history.ts","../src/handlers/get-balances/get-balances.ts","../../../packages-internal/utils/src/services/token-service/token-service.ts","../../../packages-internal/utils/src/utils/retry.ts","../../../packages-internal/utils/src/utils/coingecko-retry.ts","../../../packages-internal/utils/src/utils/charsum.ts","../../../packages-internal/utils/src/utils/array-hash.ts","../../../packages-internal/utils/src/services/token-service/coingecko-proxy-client.ts","../../../packages-internal/utils/src/services/pricing-service/exchange-rates.ts","../../../packages-internal/utils/src/utils/detail-item.ts","../src/utils/extract-token-market-data.ts","../src/handlers/get-address/get-address.ts","../src/handlers/bitcoin-send-transaction/bitcoin-send-transaction.ts","../src/handlers/bitcoin-send-transaction/schema.ts","../src/utils/is-btc-balance.ts","../src/utils/calculate-gas-limit.ts"],"names":["RpcMethod","parseManifest","rpcErrors","Environment","prodEnv","devEnv","getEnv","environment","manifest_default","BitcoinProvider","getProvider","isTestnet","proxyApiUrl","getNetworkFee","provider","high","low","medium","TokenType","TransactionType","convertBtcTransaction","tx","address","network","explorerUrl","networkToken","txAddress","getTransactionHistory","TokenUnit","VsCurrencyType","getBasicCoingeckoHttp","simplePrice","simpleTokenPrice","retry","operation","isSuccess","maxRetries","backoffPolicy","RetryBackoffPolicy","backoffPeriodMillis","retries","lastError","delay","result","err","errorMessage","retryIndex","secondsToDelay","_","msToDelay","ms","r","coingeckoRetry","response","charsum","s","i","sum","arrayHash","array","cs","Zodios","RawSimplePriceResponseSchema","SimplePriceResponseSchema","boolean","string","coingeckoProxyClient","coingeckoBasicClient","_storage","_proxyApiUrl","TokenService","storage","__privateAdd","__publicField","data","currencies","formattedData","id","tokenData","currency","__privateSet","coinIds","cacheId","__privateGet","useCoingeckoProxy","tokenAddresses","assetPlatformId","marketCap","vol24","change24","lastUpdated","shouldThrow","rawData","number","object","record","CURRENCY_EXCHANGE_RATES_URL","CURRENCY_EXCHANGE_RATES_FALLBACK_URL","ExchangeRateSchema","exchangeRateApiClient","exchangeRateFallbackApiClient","DetailItemType","currencyItem","label","value","maxDecimals","symbol","linkItem","addressItem","extractTokenMarketData","coinId","coinData","getBalances","addresses","withScripts","tokenService","coingeckoTokenId","marketData","priceInCurrency","balanceInSatoshis","utxos","unconfirmedBalanceInSatoshis","utxosUnconfirmed","balance","balanceInCurrency","balanceDisplayValue","unconfirmedBalance","unconfirmedBalanceInCurrency","acc","accountBalance","getBech32AddressFromXPub","getBtcAddressFromPubKey","networks","NetworkVMType","WalletType","getAddress","accountIndex","xpub","walletType","pubKeyBuffer","z","paramsSchema","parseRequestParams","params","isBtcBalance","hasUtxos","hasLocked","hasUnlockedUnstaked","createTransferTx","calculateGasLimit","fee","feeRate","bitcoinSendTransaction","request","approvalController","dappInfo","rawParams","success","parseError","btcBalance","to","from","amount","inputs","outputs","displayData","signingData","txHash","getTxHash","error","waitForTransactionReceipt","onTransactionConfirmed","onTransactionReverted","requestId","_approvalController","BitcoinModule"],"mappings":"2fAaA,OAAS,aAAAA,GAAW,iBAAAC,OAAqB,2BACzC,OAAS,aAAAC,OAAiB,uBCd1B,OAAS,eAAAC,MAAmB,2BAOrB,IAAMC,GAAe,CAC1B,cAAe,mCACf,YAAa,gCACf,EAEaC,GAAc,CACzB,cAAe,uCACf,YAAa,oCACf,EAEaC,GAAUC,GAAkC,CACvD,OAAQA,EAAa,CACnB,KAAKJ,EAAY,WACf,OAAOC,GACT,KAAKD,EAAY,IACf,OAAOE,EACX,CACF,ECxBA,IAAAG,GAAA,CACE,KAAQ,UACR,YAAe,GACf,QAAW,QACX,QAAW,CACT,OAAU,CACR,SAAY,GACZ,SAAY,CACV,IAAO,CACL,SAAY,iBACZ,YAAe,0BACf,SAAY,4BACd,CACF,CACF,EACA,SAAY,CACV,SAAY,GACZ,SAAY,CACV,IAAO,CACL,SAAY,mBACZ,YAAe,0BACf,SAAY,4BACd,CACF,CACF,CACF,EACA,QAAW,CACT,SAAY,CAAC,0CAA2C,yCAAyC,EACjG,WAAc,CAAC,QAAQ,CACzB,EACA,SAAY,IACZ,YAAe,CACb,IAAO,CACL,MAAS,GACT,QAAW,CAAC,yBAAyB,CACvC,CACF,EACA,gBAAmB,KACrB,ECtCA,OAAS,mBAAAC,OAAuB,4BAOzB,IAAMC,EAAc,CAAC,CAAE,UAAAC,EAAW,YAAAC,CAAY,IACnD,IAAIH,GACF,CAACE,EACD,OACA,GAAGC,CAAW,mBAAmBD,EAAY,kBAAoB,SAAS,GAC1E,GAAGC,CAAW,mBAAmBD,EAAY,cAAgB,KAAK,GAIlE,QAAQ,IAAI,gBAAkB,CAAE,MAAO,QAAQ,IAAI,eAAgB,EAAI,CAAC,CAC1E,ECVF,eAAsBE,GAAc,CAClC,UAAAF,EACA,YAAAC,CACF,EAGyB,CACvB,IAAME,EAAWJ,EAAY,CAC3B,UAAAC,EACA,YAAAC,CACF,CAAC,EAEK,CAAE,KAAAG,EAAM,IAAAC,EAAK,OAAAC,CAAO,EAAI,MAAMH,EAAS,YAAY,EAEzD,MAAO,CACL,IAAK,CACH,aAAc,OAAOE,CAAG,CAC1B,EACA,OAAQ,CACN,aAAc,OAAOC,CAAM,CAC7B,EACA,KAAM,CACJ,aAAc,OAAOF,CAAI,CAC3B,EACA,WAAY,EACd,CACF,CCjCA,OAAS,aAAAG,GAAW,mBAAAC,OAAuD,2BAQpE,IAAMC,GAAwB,CAACC,EAAsB,CAAE,QAAAC,EAAS,QAAAC,CAAQ,IAAqC,CAClH,GAAM,CAAE,YAAAC,EAAa,aAAAC,CAAa,EAAIF,EAChCG,EAAYL,EAAG,UAAU,CAAC,GAAK,GAErC,MAAO,CACL,QAASE,EAAQ,QAAQ,SAAS,EAClC,aAAc,GAAGC,CAAW,OAAOH,EAAG,IAAI,GAC1C,KAAMA,EAAG,SAAWC,EAAUI,EAC9B,QAASL,EAAG,IAAI,SAAS,EACzB,KAAMA,EAAG,KACT,eAAgB,GAChB,WAAY,CAACA,EAAG,SAChB,WAAYA,EAAG,SACf,SAAUA,EAAG,SACb,UAAWA,EAAG,aAAe,IAC7B,GAAIA,EAAG,SAAWK,EAAYJ,EAC9B,OAAQ,CACN,CACE,QAAS,KAAK,IAAID,EAAG,MAAM,EAAI,IAAMI,EAAa,UAAU,SAAS,EACrE,QAASA,EAAa,SAAS,SAAS,EACxC,KAAMA,EAAa,KACnB,OAAQA,EAAa,OACrB,KAAMP,GAAU,MAClB,CACF,EACA,OAAQG,EAAG,SAAWF,GAAgB,KAAOA,GAAgB,OAC/D,CACF,ECvBO,IAAMQ,GAAwB,MAAO,CAAE,QAAAL,EAAS,QAAAC,EAAS,YAAAX,CAAY,KAEvD,MADFF,EAAY,CAAE,UAAW,EAAQa,EAAQ,UAAY,YAAAX,CAAY,CAAC,EACjD,aAAaU,CAAO,GAEpC,IAAKD,GACrBD,GAAsBC,EAAI,CACxB,QAAAC,EACA,QAAAC,CACF,CAAC,CACH,ECrBF,OAAiC,aAAAL,OAA2C,2BAC5E,OAAS,aAAAU,OAAiB,0BCD1B,OACE,kBAAAC,EACA,yBAAAC,GACA,eAAAC,GACA,oBAAAC,OAEK,8BCsBA,IAAMC,EAAQ,MAAU,CAC7B,UAAAC,EACA,UAAAC,EACA,WAAAC,EAAa,GACb,cAAAC,EAAgBC,EAAmB,YAAY,CACjD,IAAkC,CAChC,IAAIC,EAAsB,EACtBC,EAAU,EACVC,EAEJ,KAAOD,EAAUJ,GAAY,CACvBI,EAAU,GACZ,MAAME,GAAMH,CAAmB,EAGjC,GAAI,CACF,IAAMI,EAAS,MAAMT,EAAUM,CAAO,EAEtC,GAAIL,EAAUQ,CAAM,EAClB,OAAOA,CAEX,OAASC,EAAK,CAEZH,EAAYG,CACd,CAEAL,EAAsBF,EAAcG,CAAO,EAC3CA,GACF,CAEA,IAAMK,EAAeJ,EAAY,uBAAuBA,CAAS,GAAK,sBAEtE,MAAM,IAAI,MAAMI,CAAY,CAC9B,EAIaP,EAAN,KAAyB,CAC9B,OAAO,aAA2C,CAChD,OAAQQ,GACC,KAAK,IAAI,EAAGA,CAAU,EAAI,GAErC,CAEA,OAAO,SAASC,EAAqD,CACnE,OAAQC,GACCD,EAAiB,GAE5B,CAEA,OAAO,WAAWE,EAAgD,CAChE,OAAQD,GACCC,CAEX,CACF,EAEA,SAASP,GAAMQ,EAAY,CACzB,OAAO,IAAI,QAASC,GAAM,WAAWA,EAAGD,CAAE,CAAC,CAC7C,CC9EO,IAAME,EACXlB,GAEOD,EAAM,CACX,UAAYa,GAAuBZ,EAAUY,EAAa,CAAC,EAC3D,WAAY,EACZ,cAAeR,EAAmB,SAAS,CAAC,EAC5C,UAAYe,GACWA,GAAoB,QACrB,aAAe,GAEvC,CAAC,ECpBI,SAASC,GAAQC,EAAmB,CACzC,IAAIC,EACFC,EAAM,EACR,IAAKD,EAAI,EAAGA,EAAID,EAAE,OAAQC,IACxBC,GAAOF,EAAE,WAAWC,CAAC,GAAKA,EAAI,GAEhC,OAAOC,CACT,CCJO,SAASC,EAAUC,EAAyB,CACjD,IAAIH,EACFC,EAAM,EACR,IAAKD,EAAI,EAAGA,EAAIG,EAAM,OAAQH,IAAK,CACjC,IAAMI,EAAKN,GAAQK,EAAMH,CAAC,GAAK,EAAE,EACjCC,EAAMA,EAAM,MAAQG,CACtB,CACA,OAAQ,GAAKH,GAAK,MAAM,EAAG,EAAE,CAC/B,CCXA,OAAS,UAAAI,OAAc,eACvB,OAAS,gCAAAC,GAA8B,6BAAAC,OAAiC,2BACxE,OAAS,WAAAC,EAAS,UAAAC,MAAc,MAEzB,IAAMC,EAAwBtD,GACnC,IAAIiD,GACF,GAAGjD,CAAW,mBACd,CACE,CACE,OAAQ,OACR,KAAM,gBACN,WAAY,CACV,CAAE,KAAM,MAAO,KAAM,QAAS,OAAQqD,EAAO,CAAE,EAC/C,CAAE,KAAM,gBAAiB,KAAM,QAAS,OAAQA,EAAO,CAAE,EACzD,CACE,KAAM,qBACN,KAAM,QACN,OAAQA,EAAO,EAAE,SAAS,CAC5B,EACA,CACE,KAAM,mBACN,KAAM,QACN,OAAQA,EAAO,EAAE,SAAS,CAC5B,EACA,CACE,KAAM,sBACN,KAAM,QACN,OAAQA,EAAO,EAAE,SAAS,CAC5B,EACA,CACE,KAAM,0BACN,KAAM,QACN,OAAQA,EAAO,EAAE,SAAS,CAC5B,CACF,EACA,MAAO,cACP,SAAUH,EACZ,EACA,CACE,OAAQ,OACR,KAAM,0BACN,WAAY,CACV,CAAE,KAAM,KAAM,KAAM,OAAQ,OAAQG,EAAO,CAAE,EAC7C,CAAE,KAAM,qBAAsB,KAAM,QAAS,OAAQA,EAAO,EAAE,MAAM,CAAE,EACtE,CAAE,KAAM,gBAAiB,KAAM,QAAS,OAAQA,EAAO,EAAE,MAAM,CAAE,EACjE,CACE,KAAM,qBACN,KAAM,QACN,OAAQD,EAAQ,EAAE,SAAS,CAC7B,EACA,CACE,KAAM,mBACN,KAAM,QACN,OAAQA,EAAQ,EAAE,SAAS,CAC7B,EACA,CACE,KAAM,sBACN,KAAM,QACN,OAAQA,EAAQ,EAAE,SAAS,CAC7B,CACF,EACA,MAAO,iCACP,SAAUD,EACZ,CACF,EACA,CACE,YAAa,CACX,QAAS,CACP,eAAgB,kBAClB,CACF,CACF,CACF,EL5DF,IAAMI,GAAuBrC,GAAsB,EAZnDsC,EAAAC,EAcaC,EAAN,KAAmB,CAIxB,YAAY,CAAE,QAAAC,EAAS,YAAA3D,CAAY,EAA+C,CAHlF4D,EAAA,KAAAJ,EAAA,QACAI,EAAA,KAAAH,EAAA,QAuJAI,EAAA,KAAQ,+BAA+B,CACrCC,EACAC,EAAa,CAAC9C,EAAe,GAAG,IACR,CACxB,IAAM+C,EAAqC,CAAC,EAC5C,cAAO,KAAKF,CAAI,EAAE,QAASG,GAAO,CAChC,IAAMC,EAAYJ,EAAKG,CAAE,EACzBD,EAAcC,CAAE,EAAI,CAAC,EACrBF,EAAW,QAASI,GAA6B,CAC/CH,EAAcC,CAAE,EAAI,CAClB,CAACE,CAAQ,EAAG,CACV,MAAOD,IAAYC,CAAQ,EAC3B,SAAUD,IAAY,GAAGC,CAAQ,aAAa,EAC9C,MAAOD,IAAY,GAAGC,CAAQ,UAAU,EACxC,UAAWD,IAAY,GAAGC,CAAQ,aAAa,CACjD,CACF,CACF,CAAC,CACH,CAAC,EACMH,CACT,GAxKEI,EAAA,KAAKZ,EAAWG,GAChBS,EAAA,KAAKX,EAAezD,EACtB,CAOA,MAAM,eAAe,CACnB,QAAAqE,EAAU,CAAC,EACX,WAAAN,EAAa,CAAC9C,EAAe,GAAG,CAClC,EAAgE,CAC9D,IAAI6C,EAIEQ,EAAU,kBAFJD,EAAU,GAAGvB,EAAUuB,CAAO,CAAC,IAAIN,EAAW,SAAS,CAAC,GAAK,GAAGA,EAAW,SAAS,CAAC,EAE5D,GAIrC,GAFAD,EAAOS,EAAA,KAAKf,IAAU,MAA2Bc,CAAO,EAEpDR,EAAM,OAAOA,EAEjB,GAAI,CACFA,EAAO,MAAMtB,EAAgBgC,GAC3B,KAAK,YAAY,CACf,QAAAH,EACA,WAAAN,EACA,UAAW,GACX,MAAO,GACP,SAAU,GACV,kBAAAS,CACF,CAAC,CACH,CACF,MAAQ,CACNV,EAAO,MACT,CACA,OAAAS,EAAA,KAAKf,IAAU,MAAMc,EAASR,CAAI,EAC3BA,CACT,CASA,MAAM,qBACJW,EACAC,EACAP,EAA2BlD,EAAe,IACA,CAC1C,IAAI6C,EAIEQ,EAAU,sCAFJ,GAAGxB,EAAU2B,CAAc,CAAC,IAAIC,CAAe,IAAIP,CAAQ,EAEd,GAGzD,GAFAL,EAAOS,EAAA,KAAKf,IAAU,MAA2Bc,CAAO,EAEpDR,EAAM,OAAOA,EAEjB,GAAI,CACFA,EAAO,MAAMtB,EAAgBgC,GAC3B,KAAK,uBAAuB,CAC1B,gBAAAE,EACA,eAAAD,EACA,SAAAN,EACA,kBAAAK,CACF,CAAC,CACH,CACF,MAAQ,CACNV,EAAO,MACT,CACA,OAAAS,EAAA,KAAKf,IAAU,MAAMc,EAASR,CAAI,EAC3BA,CACT,CAEA,MAAc,uBAAuB,CACnC,gBAAAY,EACA,eAAAD,EACA,SAAAN,EAAWlD,EAAe,IAC1B,kBAAAuD,EAAoB,EACtB,EAKiC,CAC/B,OAAIA,EACKlB,EAAqBiB,EAAA,KAAKd,EAAY,EAAE,+BAA+B,OAAW,CACvF,OAAQ,CACN,GAAIiB,CACN,EACA,QAAS,CACP,mBAAoBD,EACpB,cAAe,CAACN,CAAQ,EACxB,mBAAoB,GACpB,iBAAkB,GAClB,oBAAqB,EACvB,CACF,CAAC,EAGI/C,GAAiBmC,GAAsB,CAC5C,gBAAAmB,EACA,eAAAD,EACA,WAAY,CAACN,CAAQ,EACrB,UAAW,GACX,MAAO,GACP,SAAU,EACZ,CAAC,CACH,CAEA,MAAc,YAAY,CACxB,QAAAE,EAAU,CAAC,EACX,WAAAN,EAAa,CAAC9C,EAAe,GAAG,EAChC,UAAA0D,EAAY,GACZ,MAAAC,EAAQ,GACR,SAAAC,EAAW,GACX,YAAAC,EAAc,GACd,kBAAAN,EAAoB,GACpB,YAAAO,EAAc,EAChB,EAAsF,CACpF,GAAIP,EAAmB,CACrB,IAAMQ,EAAU,MAAM1B,EAAqBiB,EAAA,KAAKd,EAAY,EAAE,YAAY,OAAW,CACnF,QAAS,CACP,IAAKY,GAAS,KAAK,GAAG,EACtB,cAAeN,EAAW,KAAK,GAAG,EAClC,mBAAoB,OAAOY,CAAS,EACpC,iBAAkB,OAAOC,CAAK,EAC9B,oBAAqB,OAAOC,CAAQ,EACpC,wBAAyB,OAAOC,CAAW,CAC7C,CACF,CAAC,EACD,OAAO,KAAK,6BAA6BE,EAASjB,CAAU,CAC9D,CACA,OAAO5C,GAAYoC,GAAsB,CACvC,QAAAc,EACA,WAAAN,EACA,UAAAY,EACA,MAAAC,EACA,SAAAC,EACA,YAAAC,EACA,YAAAC,CACF,CAAC,CACH,CAuBF,EA7KEvB,EAAA,YACAC,EAAA,YMhBF,OAAS,UAAAR,OAAc,eACvB,OAAY,UAAAgC,GAAQ,UAAAC,GAAQ,UAAAC,GAAQ,UAAA9B,OAAc,MAElD,IAAM+B,GACJ,2FAEIC,GAAuC,mEAEvCC,GAAqBJ,GAAO,CAChC,KAAM7B,GAAO,EACb,IAAK8B,GAAOF,GAAO,CAAC,CACtB,CAAC,EAIKM,GAAwB,IAAItC,GAAOmC,GAA6B,CACpE,CACE,OAAQ,MACR,KAAM,GACN,MAAO,mBACP,SAAUE,EACZ,CACF,CAAC,EAEKE,GAAgC,IAAIvC,GAAOoC,GAAsC,CACrF,CACE,OAAQ,MACR,KAAM,GACN,MAAO,mBACP,SAAUC,EACZ,CACF,CAAC,EC/BD,OAQE,kBAAAG,MAEK,2BAEA,IAAMC,EAAe,CAACC,EAAeC,EAAeC,EAAqBC,KAAkC,CAChH,MAAAH,EACA,KAAMF,EAAe,SACrB,MAAAG,EACA,YAAAC,EACA,OAAAC,CACF,GAaO,IAAMC,GAAW,CAACJ,EAAeC,KAAoC,CAC1E,MAAAD,EACA,MAAAC,EACA,KAAMH,EAAe,IACvB,GAEaO,EAAc,CAACL,EAAeC,KAAgC,CACzE,MAAAD,EACA,KAAMF,EAAe,QACrB,MAAAG,CACF,GCvCO,IAAMK,GAAyB,CACpCC,EACA/B,EACAL,IACoB,CACpB,IAAMqC,EAAWrC,IAAOoC,CAAM,IAAI/B,GAAY,EAAE,GAAK,CAAC,EAEtD,MAAO,CACL,gBAAiBgC,EAAS,OAAS,OACnC,UAAWA,EAAS,WAAa,OACjC,MAAOA,EAAS,OAAS,OACzB,SAAUA,EAAS,UAAY,MACjC,CACF,ETEO,IAAMC,EAAc,MAAO,CAChC,UAAAC,EACA,SAAAlC,EACA,QAAAxD,EACA,YAAA2F,EACA,YAAAtG,EACA,QAAA2D,CACF,IAA6D,CAC3D,IAAMzD,EAAWJ,EAAY,CAC3B,UAAW,EAAQa,EAAQ,UAC3B,YAAAX,CACF,CAAC,EAEKuG,EAAe,IAAI7C,EAAa,CAAE,YAAA1D,EAAa,QAAA2D,CAAQ,CAAC,EACxD6C,EAAmB7F,EAAQ,kBAAkB,UAAU,cAEvD8F,EADa,OAAOtC,GAAa,UAAY,OAAOqC,GAAqB,SAE3E,MAAMD,EAAa,eAAe,CAChC,QAAS,CAACC,CAAgB,EAC1B,WAAY,CAACrC,CAAQ,CACvB,CAAC,EACD,OACE,CAAE,gBAAAuC,EAAiB,SAAA7B,EAAU,UAAAF,EAAW,MAAAC,CAAM,EAAIqB,GACtDO,GAAoB,GACpBrC,EACAsC,CACF,EAsDA,OApDiB,MAAM,QAAQ,WAC7BJ,EAAU,IAAI,MAAO3F,GAAY,CAC/B,GAAM,CACJ,QAASiG,EACT,MAAAC,EACA,mBAAoBC,EACpB,iBAAAC,CACF,EAAI,MAAM5G,EAAS,eAAeQ,EAAS4F,CAAW,EAEhDS,EAAU,IAAI/F,GAAU2F,EAAmBhG,EAAQ,aAAa,SAAUA,EAAQ,aAAa,MAAM,EACrGqG,EAAoBN,IAAoB,OAAYK,EAAQ,IAAIL,CAAe,EAAI,OACnFO,EAAsBF,EAAQ,UAAU,EAExCG,EAAqB,IAAIlG,GAC7B6F,EACAlG,EAAQ,aAAa,SACrBA,EAAQ,aAAa,MACvB,EACMwG,EACJT,IAAoB,OAAYQ,EAAmB,IAAIR,CAAe,EAAI,OAEtEZ,GAASnF,EAAQ,aAAa,OAEpC,MAAO,CACL,CAACD,CAAO,EAAG,CACT,CAACoF,EAAM,EAAG,CACR,GAAGnF,EAAQ,aACX,MAAAiG,EACA,iBAAAE,EACA,YAAaN,GAAoB,GACjC,KAAMlG,GAAU,OAChB,QAASyG,EAAQ,UAAU,EAC3B,oBAAAE,EACA,kBAAmBD,GAAmB,UAAU,CAAE,QAAS,EAAG,SAAU,EAAK,CAAC,EAC9E,4BAA6BA,GAAmB,UAAU,CAAE,QAAS,CAAE,CAAC,EACxE,gBAAAN,EACA,UAAA/B,EACA,MAAAC,EACA,SAAAC,EACA,mBAAoBqC,EAAmB,UAAU,EACjD,+BAAgCA,EAAmB,UAAU,EAC7D,6BAA8BC,GAA8B,UAAU,CACpE,QAAS,EACT,SAAU,EACZ,CAAC,EACD,uCAAwCA,GAA8B,UAAU,CAAE,QAAS,CAAE,CAAC,CAChG,CACF,CACF,CACF,CAAC,CACH,GAEgB,OAAO,CAACC,EAAKC,IACvBA,EAAe,SAAW,WACrBD,EAGF,CACL,GAAGA,EACH,GAAGC,EAAe,KACpB,EACC,CAAC,CAAC,CACP,EU1GA,OAAS,4BAAAC,GAA0B,2BAAAC,OAA+B,4BAClE,OAAS,YAAAC,MAAgB,gBACzB,OAAS,iBAAAC,GAAe,cAAAC,MAAkB,2BAC1C,OAAS,aAAApI,OAAiB,uBAInB,IAAMqI,GAAa,MAAO,CAC/B,aAAAC,EACA,KAAAC,EACA,UAAA9H,EACA,WAAA+H,CACF,IAA+C,CAC7C,OAAQA,EAAY,CAClB,KAAKJ,EAAW,SAChB,KAAKA,EAAW,OAChB,KAAKA,EAAW,SACd,MAAO,CACL,CAACD,GAAc,OAAO,EAAGH,GACvBO,EACAD,EACA7H,EAAYyH,EAAS,QAAUA,EAAS,OAC1C,CACF,EAEF,KAAKE,EAAW,WAChB,KAAKA,EAAW,SAAU,CACxB,IAAMK,EAAe,OAAO,KAAKF,EAAM,KAAK,EAC5C,MAAO,CACL,CAACJ,GAAc,OAAO,EAAGF,GAAwBQ,EAAchI,EAAYyH,EAAS,QAAUA,EAAS,OAAO,CAChH,CACF,CACA,QACE,MAAMlI,GAAU,cAAc,4BAA4BwI,CAAU,EAAE,CAC1E,CACF,ECpCA,OACE,aAAA1I,OAQK,2BCTP,OAAS,KAAA4I,MAAS,MAElB,IAAMC,GAAeD,EAAE,OAAO,CAC5B,KAAMA,EAAE,OAAO,EACf,GAAIA,EAAE,OAAO,EACb,OAAQA,EAAE,OAAO,EACjB,QAASA,EAAE,OAAO,CACpB,CAAC,EAEYE,GAAsBC,GAC1BF,GAAa,UAAUE,CAAM,EDCtC,OAAS,aAAA7I,MAAiB,uBETnB,IAAM8I,GAAgBrB,GAA+D,CAC1F,GAAI,CAACA,EACH,MAAO,GAGT,IAAMsB,EAAW,UAAWtB,EACtBuB,EAAY,WAAYvB,EACxBwB,EAAsB,qBAAsBxB,EAElD,OAAOsB,GAAY,CAACE,GAAuB,CAACD,CAC9C,EFGA,OAA0B,oBAAAE,OAA+C,4BGXlE,IAAMC,GAAoB,CAACC,EAAaC,IACtCD,EAAMC,EHsBR,IAAMC,GAAyB,MAAO,CAC3C,QAAAC,EACA,QAAAlI,EACA,mBAAAmI,EACA,YAAA9I,CACF,IAAoC,CAClC,GAAM,CAAE,SAAA+I,EAAU,OAAQC,CAAU,EAAIH,EAElC,CAAE,QAAAI,EAAS,KAAMd,EAAQ,MAAOe,CAAW,EAAIhB,GAAmBc,CAAS,EAEjF,GAAI,CAACC,EACH,eAAQ,MAAM,iBAAkBC,CAAU,EACnC,CACL,MAAO5J,EAAU,cAAc,CAAE,QAAS,iCAAkC,KAAM,CAAE,MAAO4J,CAAW,CAAE,CAAC,CAC3G,EAIF,IAAMC,GADW,MAAM/C,EAAY,CAAE,UAAW,CAAC+B,EAAO,IAAI,EAAG,QAAAxH,EAAS,YAAAX,EAAa,YAAa,EAAK,CAAC,KAC1EmI,EAAO,IAAI,IAAIxH,EAAQ,aAAa,MAAM,EAExE,GAAI,CAACyH,GAAae,CAAU,EAC1B,MAAO,CACL,MAAO7J,EAAU,SAAS,iDAAiD,CAC7E,EAGF,IAAMY,EAAWJ,EAAY,CAC3B,UAAW,EAAQa,EAAQ,UAC3B,YAAAX,CACF,CAAC,EAEK,CAAE,GAAAoJ,EAAI,KAAAC,EAAM,OAAAC,EAAQ,QAAAX,CAAQ,EAAIR,EAEhC,CAAE,OAAAoB,EAAQ,QAAAC,EAAS,IAAAd,CAAI,EAAIF,GAC/BY,EACAC,EACAC,EACAX,EACAQ,EAAW,MACXjJ,EAAS,WAAW,CACtB,EAEA,GAAI,CAACqJ,GAAU,CAACC,EACd,MAAO,CACL,MAAOlK,EAAU,SAAS,8BAA8B,CAC1D,EAGF,IAAMmK,EAA2B,CAC/B,MAAO,sBACP,QAAS,CACP,QAAS9I,EAAQ,QACjB,KAAMA,EAAQ,UACd,QAASA,EAAQ,OACnB,EACA,QAAS,CACP,CACE,MAAO,sBACP,MAAO,CACLoF,GAAS,UAAWgD,CAAQ,EAC5B/C,EAAY,OAAQqD,CAAI,EACxBrD,EAAY,KAAMoD,CAAE,EACpB1D,EAAa,SAAU,OAAO4D,CAAM,EAAG3I,EAAQ,aAAa,SAAUA,EAAQ,aAAa,MAAM,CACnG,CACF,CACF,EACA,mBAAoB,EACtB,EAEM+I,EAA2B,CAC/B,KAAMtK,GAAU,yBAChB,QAASiK,EACT,KAAM,CACJ,GAAAD,EACA,OAAAE,EACA,IAAAZ,EACA,QAAAC,EACA,SAAUF,GAAkBC,EAAKC,CAAO,EACxC,OAAAY,EACA,QAAAC,EACA,QAASL,CACX,CACF,EAEM1G,EAAW,MAAMqG,EAAmB,gBAAgB,CAAE,QAAAD,EAAS,YAAAY,EAAa,YAAAC,CAAY,CAAC,EAE/F,GAAI,UAAWjH,EACb,MAAO,CACL,MAAOA,EAAS,KAClB,EAGF,IAAIkH,EAEJ,GAAI,CACFA,EAAS,MAAMC,GAAU1J,EAAUuC,CAAQ,CAC7C,OAASoH,EAAO,CACd,MAAO,CACL,MAAOvK,EAAU,SAAS,CAAE,QAAS,iCAAkC,KAAM,CAAE,MAAOuK,CAAM,CAAE,CAAC,CACjG,CACF,CAEA,OAAAC,GAA0B,CACxB,SAAA5J,EACA,OAAQyJ,EACR,uBAAwBb,EAAmB,uBAC3C,sBAAuBA,EAAmB,sBAG1C,UAAWD,EAAQ,SACrB,CAAC,EAEM,CACL,OAAQc,CACV,CACF,EAEMC,GAAY,MAAO1J,EAA2BuC,IAC9C,WAAYA,EACPA,EAAS,OAGXvC,EAAS,WAAWuC,EAAS,UAAU,EAG1CqH,GAA4B,MAAO,CACvC,SAAA5J,EACA,OAAAyJ,EACA,uBAAAI,EACA,sBAAAC,EACA,UAAAC,CACF,IAMM,CACJ,GAAI,CACF,MAAM/J,EAAS,UAAUyJ,CAAM,EAC/BI,EAAuBJ,EAAQM,CAAS,CAC1C,OAASjI,EAAK,CACZ,QAAQ,MAAMA,CAAG,EACjBgI,EAAsBL,EAAQM,CAAS,CACzC,CACF,ElB5KA,IAAAxG,EAAAyG,EA0BaC,GAAN,KAAsC,CAI3C,YAAY,CACV,YAAAxK,EACA,mBAAAmJ,CACF,EAGG,CATHlF,EAAA,KAAAH,EAAA,QACAG,EAAA,KAAAsG,EAAA,QASE,GAAM,CAAE,YAAAlK,CAAY,EAAIN,GAAOC,CAAW,EAE1CyE,EAAA,KAAK8F,EAAsBpB,GAC3B1E,EAAA,KAAKX,EAAezD,EACtB,CAEA,YAAYW,EAAmC,CAC7C,OAAOb,EAAY,CACjB,UAAW,EAAQa,EAAQ,UAC3B,YAAa4D,EAAA,KAAKd,EACpB,CAAC,CACH,CAEA,WAAW,CAAE,aAAAmE,EAAc,KAAAC,EAAM,UAAA9H,EAAW,WAAA+H,CAAW,EAAkD,CACvG,OAAOH,GAAW,CAAE,aAAAC,EAAc,KAAAC,EAAM,UAAA9H,EAAW,WAAA+H,CAAW,CAAC,CACjE,CAEA,YAAY,CAAE,UAAAzB,EAAW,SAAAlC,EAAU,QAAAxD,EAAS,QAAAgD,CAAQ,EAAsB,CACxE,OAAOyC,EAAY,CACjB,UAAAC,EACA,SAAAlC,EACA,QAAAxD,EACA,YAAa4D,EAAA,KAAKd,GAClB,QAAAE,CACF,CAAC,CACH,CAEA,aAAoC,CAClC,IAAM5B,EAAS1C,GAAcO,EAAY,EACzC,OAAOmC,EAAO,QAAUA,EAAO,KAAO,MACxC,CAEA,cAAcpB,EAAwC,CACpD,OAAOV,GAAc,CACnB,UAAW,EAAQU,EAAQ,UAC3B,YAAa4D,EAAA,KAAKd,EACpB,CAAC,CACH,CAEA,MAAM,sBAAsB,CAAE,QAAA/C,EAAS,QAAAC,CAAQ,EAA0B,CACvE,MAAO,CACL,aAAc,MAAMI,GAAsB,CACxC,QAAAL,EACA,QAAAC,EACA,YAAa4D,EAAA,KAAKd,EACpB,CAAC,CACH,CACF,CAEA,UAAUrB,EAAY,CACpB,OAAO,QAAQ,QAAQ,CAAC,CAAC,CAC3B,CAEA,MAAM,aAAayG,EAAqBlI,EAAkB,CACxD,OAAQkI,EAAQ,OAAQ,CACtB,KAAKzJ,GAAU,yBACb,OAAOwJ,GAAuB,CAC5B,QAAAC,EACA,QAAAlI,EACA,mBAAoB4D,EAAA,KAAK2F,GACzB,YAAa3F,EAAA,KAAKd,EACpB,CAAC,EACH,QACE,MAAO,CAAE,MAAOnE,GAAU,mBAAmB,UAAUuJ,EAAQ,MAAM,gBAAgB,CAAE,CAC3F,CACF,CACF,EA5EEpF,EAAA,YACAyG,EAAA","sourcesContent":["import type {\n Module,\n Manifest,\n NetworkFees,\n GetTransactionHistory,\n RpcRequest,\n Network,\n Environment,\n GetBalancesParams,\n GetAddressParams,\n GetAddressResponse,\n ApprovalController,\n} from '@avalabs/vm-module-types';\nimport { RpcMethod, parseManifest } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { getEnv } from './env';\n\nimport ManifestJson from '../manifest.json';\nimport { getNetworkFee } from './handlers/get-network-fee/get-network-fee';\nimport { getTransactionHistory } from './handlers/get-transaction-history/get-transaction-history';\nimport { getBalances } from './handlers/get-balances/get-balances';\nimport { getAddress } from './handlers/get-address/get-address';\nimport { bitcoinSendTransaction } from './handlers/bitcoin-send-transaction/bitcoin-send-transaction';\nimport type { BitcoinProvider } from '@avalabs/core-wallets-sdk';\nimport { getProvider } from './utils/get-provider';\n\nexport class BitcoinModule implements Module {\n #proxyApiUrl: string;\n #approvalController: ApprovalController;\n\n constructor({\n environment,\n approvalController,\n }: {\n environment: Environment;\n approvalController: ApprovalController;\n }) {\n const { proxyApiUrl } = getEnv(environment);\n\n this.#approvalController = approvalController;\n this.#proxyApiUrl = proxyApiUrl;\n }\n\n getProvider(network: Network): BitcoinProvider {\n return getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl: this.#proxyApiUrl,\n });\n }\n\n getAddress({ accountIndex, xpub, isTestnet, walletType }: GetAddressParams): Promise<GetAddressResponse> {\n return getAddress({ accountIndex, xpub, isTestnet, walletType });\n }\n\n getBalances({ addresses, currency, network, storage }: GetBalancesParams) {\n return getBalances({\n addresses,\n currency,\n network,\n proxyApiUrl: this.#proxyApiUrl,\n storage,\n });\n }\n\n getManifest(): Manifest | undefined {\n const result = parseManifest(ManifestJson);\n return result.success ? result.data : undefined;\n }\n\n getNetworkFee(network: Network): Promise<NetworkFees> {\n return getNetworkFee({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl: this.#proxyApiUrl,\n });\n }\n\n async getTransactionHistory({ address, network }: GetTransactionHistory) {\n return {\n transactions: await getTransactionHistory({\n address,\n network,\n proxyApiUrl: this.#proxyApiUrl,\n }),\n };\n }\n\n getTokens(_: Network) {\n return Promise.resolve([]);\n }\n\n async onRpcRequest(request: RpcRequest, network: Network) {\n switch (request.method) {\n case RpcMethod.BITCOIN_SEND_TRANSACTION:\n return bitcoinSendTransaction({\n request,\n network,\n approvalController: this.#approvalController,\n proxyApiUrl: this.#proxyApiUrl,\n });\n default:\n return { error: rpcErrors.methodNotSupported(`Method ${request.method} not supported`) };\n }\n }\n}\n","import { Environment } from '@avalabs/vm-module-types';\n\ntype Env = {\n glacierApiUrl: string;\n proxyApiUrl: string;\n};\n\nexport const prodEnv: Env = {\n glacierApiUrl: 'https://glacier-api.avax.network',\n proxyApiUrl: 'https://proxy-api.avax.network',\n};\n\nexport const devEnv: Env = {\n glacierApiUrl: 'https://glacier-api-dev.avax.network',\n proxyApiUrl: 'https://proxy-api-dev.avax.network',\n};\n\nexport const getEnv = (environment: Environment): Env => {\n switch (environment) {\n case Environment.PRODUCTION:\n return prodEnv;\n case Environment.DEV:\n return devEnv;\n }\n};\n","{\n \"name\": \"Bitcoin\",\n \"description\": \"\",\n \"version\": \"0.0.1\",\n \"sources\": {\n \"module\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/bundle.js\",\n \"packageName\": \"@avalabs/bitcoin-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n },\n \"provider\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/provider.js\",\n \"packageName\": \"@avalabs/bitcoin-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n }\n },\n \"network\": {\n \"chainIds\": [\"bip122:000000000019d6689c085ae165831e93\", \"bip122:000000000933ea01ad0ee984209779ba\"],\n \"namespaces\": [\"bip122\"]\n },\n \"cointype\": \"0\",\n \"permissions\": {\n \"rpc\": {\n \"dapps\": true,\n \"methods\": [\"bitcoin_sendTransaction\"]\n }\n },\n \"manifestVersion\": \"0.0\"\n}\n","import { BitcoinProvider } from '@avalabs/core-wallets-sdk';\n\ntype ProviderParams = {\n isTestnet: boolean;\n proxyApiUrl: string;\n};\n\nexport const getProvider = ({ isTestnet, proxyApiUrl }: ProviderParams): BitcoinProvider =>\n new BitcoinProvider(\n !isTestnet,\n undefined,\n `${proxyApiUrl}/proxy/nownodes/${isTestnet ? 'btcbook-testnet' : 'btcbook'}`,\n `${proxyApiUrl}/proxy/nownodes/${isTestnet ? 'btc-testnet' : 'btc'}`,\n\n // The Glacier API key is only needed in development to bypass rate limits.\n // It should never be used in production.\n process.env.GLACIER_API_KEY ? { token: process.env.GLACIER_API_KEY } : {},\n );\n","import type { NetworkFees } from '@avalabs/vm-module-types';\n\nimport { getProvider } from '../../utils/get-provider';\n\n/**\n * Returns {@link NetworkFees} based on `estimatesmartfee` RPC call\n */\nexport async function getNetworkFee({\n isTestnet,\n proxyApiUrl,\n}: {\n isTestnet: boolean;\n proxyApiUrl: string;\n}): Promise<NetworkFees> {\n const provider = getProvider({\n isTestnet,\n proxyApiUrl,\n });\n\n const { high, low, medium } = await provider.getFeeRates();\n\n return {\n low: {\n maxFeePerGas: BigInt(low),\n },\n medium: {\n maxFeePerGas: BigInt(medium),\n },\n high: {\n maxFeePerGas: BigInt(high),\n },\n isFixedFee: false,\n };\n}\n","import { TokenType, TransactionType, type Network, type Transaction } from '@avalabs/vm-module-types';\nimport type { BitcoinHistoryTx } from '@avalabs/core-wallets-sdk';\n\ntype ConverterOptions = {\n address: string;\n network: Network;\n};\n\nexport const convertBtcTransaction = (tx: BitcoinHistoryTx, { address, network }: ConverterOptions): Transaction => {\n const { explorerUrl, networkToken } = network;\n const txAddress = tx.addresses[0] ?? '';\n\n return {\n chainId: network.chainId.toString(),\n explorerLink: `${explorerUrl}/tx/${tx.hash}`,\n from: tx.isSender ? address : txAddress,\n gasUsed: tx.fee.toString(),\n hash: tx.hash,\n isContractCall: false,\n isIncoming: !tx.isSender,\n isOutgoing: tx.isSender,\n isSender: tx.isSender,\n timestamp: tx.receivedTime * 1000,\n to: tx.isSender ? txAddress : address,\n tokens: [\n {\n amount: (Math.abs(tx.amount) / 10 ** networkToken.decimals).toString(),\n decimal: networkToken.decimals.toString(),\n name: networkToken.name,\n symbol: networkToken.symbol,\n type: TokenType.NATIVE,\n },\n ],\n txType: tx.isSender ? TransactionType.SEND : TransactionType.RECEIVE,\n };\n};\n","import type { Network } from '@avalabs/vm-module-types';\n\nimport { getProvider } from '../../utils/get-provider';\n\nimport { convertBtcTransaction } from './convert-btc-transaction';\n\ntype GetBtcTransactionHistoryOptions = {\n network: Network;\n address: string;\n proxyApiUrl: string;\n};\n\nexport const getTransactionHistory = async ({ address, network, proxyApiUrl }: GetBtcTransactionHistoryOptions) => {\n const provider = getProvider({ isTestnet: Boolean(network.isTestnet), proxyApiUrl });\n const rawHistory = await provider.getTxHistory(address);\n\n return rawHistory.map((tx) =>\n convertBtcTransaction(tx, {\n address,\n network,\n }),\n );\n};\n","import { type GetBalancesParams, TokenType, type TokenWithBalanceBTC } from '@avalabs/vm-module-types';\nimport { TokenUnit } from '@avalabs/core-utils-sdk';\nimport type { VsCurrencyType } from '@avalabs/core-coingecko-sdk';\n\nimport { TokenService } from '@internal/utils';\n\nimport { getProvider } from '../../utils/get-provider';\nimport { extractTokenMarketData } from '../../utils/extract-token-market-data';\n\ntype GetBtcBalancesResponse = Record<string, Record<string, TokenWithBalanceBTC>>;\n\ntype GetBTCBalancesParams = Omit<GetBalancesParams, 'currency'> & {\n proxyApiUrl: string;\n withScripts?: boolean;\n currency?: string;\n};\n\nexport const getBalances = async ({\n addresses,\n currency,\n network,\n withScripts,\n proxyApiUrl,\n storage,\n}: GetBTCBalancesParams): Promise<GetBtcBalancesResponse> => {\n const provider = getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl,\n });\n\n const tokenService = new TokenService({ proxyApiUrl, storage });\n const coingeckoTokenId = network.pricingProviders?.coingecko.nativeTokenId;\n const withPrices = typeof currency === 'string' && typeof coingeckoTokenId === 'string';\n const marketData = withPrices\n ? await tokenService.getSimplePrice({\n coinIds: [coingeckoTokenId],\n currencies: [currency] as VsCurrencyType[],\n })\n : undefined;\n const { priceInCurrency, change24, marketCap, vol24 } = extractTokenMarketData(\n coingeckoTokenId ?? '',\n currency,\n marketData,\n );\n\n const balances = await Promise.allSettled(\n addresses.map(async (address) => {\n const {\n balance: balanceInSatoshis,\n utxos,\n balanceUnconfirmed: unconfirmedBalanceInSatoshis,\n utxosUnconfirmed,\n } = await provider.getUtxoBalance(address, withScripts);\n\n const balance = new TokenUnit(balanceInSatoshis, network.networkToken.decimals, network.networkToken.symbol);\n const balanceInCurrency = priceInCurrency !== undefined ? balance.mul(priceInCurrency) : undefined;\n const balanceDisplayValue = balance.toDisplay();\n\n const unconfirmedBalance = new TokenUnit(\n unconfirmedBalanceInSatoshis,\n network.networkToken.decimals,\n network.networkToken.symbol,\n );\n const unconfirmedBalanceInCurrency =\n priceInCurrency !== undefined ? unconfirmedBalance.mul(priceInCurrency) : undefined;\n\n const symbol = network.networkToken.symbol;\n\n return {\n [address]: {\n [symbol]: {\n ...network.networkToken,\n utxos,\n utxosUnconfirmed,\n coingeckoId: coingeckoTokenId ?? '',\n type: TokenType.NATIVE,\n balance: balance.toSubUnit(),\n balanceDisplayValue,\n balanceInCurrency: balanceInCurrency?.toDisplay({ fixedDp: 2, asNumber: true }),\n balanceCurrencyDisplayValue: balanceInCurrency?.toDisplay({ fixedDp: 2 }),\n priceInCurrency,\n marketCap,\n vol24,\n change24,\n unconfirmedBalance: unconfirmedBalance.toSubUnit(),\n unconfirmedBalanceDisplayValue: unconfirmedBalance.toDisplay(),\n unconfirmedBalanceInCurrency: unconfirmedBalanceInCurrency?.toDisplay({\n fixedDp: 2,\n asNumber: true,\n }),\n unconfirmedBalanceCurrencyDisplayValue: unconfirmedBalanceInCurrency?.toDisplay({ fixedDp: 2 }),\n },\n },\n };\n }),\n );\n\n return balances.reduce((acc, accountBalance) => {\n if (accountBalance.status === 'rejected') {\n return acc;\n }\n\n return {\n ...acc,\n ...accountBalance.value,\n };\n }, {});\n};\n","import {\n VsCurrencyType,\n getBasicCoingeckoHttp,\n simplePrice,\n simpleTokenPrice,\n type SimplePriceParams,\n} from '@avalabs/core-coingecko-sdk';\nimport type { Storage, RawSimplePriceResponse, SimplePriceResponse } from '@avalabs/vm-module-types';\nimport { coingeckoRetry } from '../../utils/coingecko-retry';\nimport { arrayHash } from '../../utils/array-hash';\nimport { coingeckoProxyClient } from './coingecko-proxy-client';\n\nconst coingeckoBasicClient = getBasicCoingeckoHttp();\n\nexport class TokenService {\n #storage?: Storage;\n #proxyApiUrl: string;\n\n constructor({ storage, proxyApiUrl }: { proxyApiUrl: string; storage?: Storage }) {\n this.#storage = storage;\n this.#proxyApiUrl = proxyApiUrl;\n }\n\n /**\n * Get token price with market data first on coingecko (free tier) directly,\n * if we get 429 error, retry it on coingecko proxy (paid service)\n * @returns token price with market data\n */\n async getSimplePrice({\n coinIds = [],\n currencies = [VsCurrencyType.USD],\n }: SimplePriceParams): Promise<SimplePriceResponse | undefined> {\n let data: SimplePriceResponse | undefined;\n\n const key = coinIds ? `${arrayHash(coinIds)}-${currencies.toString()}` : `${currencies.toString()}`;\n\n const cacheId = `getSimplePrice-${key}`;\n\n data = this.#storage?.get?.<SimplePriceResponse>(cacheId);\n\n if (data) return data;\n\n try {\n data = await coingeckoRetry((useCoingeckoProxy) =>\n this.simplePrice({\n coinIds,\n currencies,\n marketCap: true,\n vol24: true,\n change24: true,\n useCoingeckoProxy,\n }),\n );\n } catch {\n data = undefined;\n }\n this.#storage?.set?.(cacheId, data);\n return data;\n }\n\n /**\n * Get token price with market data for a list of addresses\n * @param tokenAddresses the token addresses\n * @param assetPlatformId The platform id for all the tokens in the list\n * @param currency the currency to be used\n * @returns a list of token price with market data\n */\n async getPricesByAddresses(\n tokenAddresses: string[],\n assetPlatformId: string,\n currency: VsCurrencyType = VsCurrencyType.USD,\n ): Promise<SimplePriceResponse | undefined> {\n let data: SimplePriceResponse | undefined;\n\n const key = `${arrayHash(tokenAddresses)}-${assetPlatformId}-${currency}`;\n\n const cacheId = `getPricesWithMarketDataByAddresses-${key}`;\n data = this.#storage?.get?.<SimplePriceResponse>(cacheId);\n\n if (data) return data;\n\n try {\n data = await coingeckoRetry((useCoingeckoProxy) =>\n this.fetchPricesByAddresses({\n assetPlatformId,\n tokenAddresses,\n currency,\n useCoingeckoProxy,\n }),\n );\n } catch {\n data = undefined;\n }\n this.#storage?.set?.(cacheId, data);\n return data;\n }\n\n private async fetchPricesByAddresses({\n assetPlatformId,\n tokenAddresses,\n currency = VsCurrencyType.USD,\n useCoingeckoProxy = false,\n }: {\n assetPlatformId: string;\n tokenAddresses: string[];\n currency: VsCurrencyType;\n useCoingeckoProxy?: boolean;\n }): Promise<SimplePriceResponse> {\n if (useCoingeckoProxy) {\n return coingeckoProxyClient(this.#proxyApiUrl).simplePriceByContractAddresses(undefined, {\n params: {\n id: assetPlatformId,\n },\n queries: {\n contract_addresses: tokenAddresses,\n vs_currencies: [currency],\n include_market_cap: true,\n include_24hr_vol: true,\n include_24hr_change: true,\n },\n });\n }\n\n return simpleTokenPrice(coingeckoBasicClient, {\n assetPlatformId,\n tokenAddresses,\n currencies: [currency],\n marketCap: true,\n vol24: true,\n change24: true,\n });\n }\n\n private async simplePrice({\n coinIds = [],\n currencies = [VsCurrencyType.USD],\n marketCap = false,\n vol24 = false,\n change24 = false,\n lastUpdated = false,\n useCoingeckoProxy = false,\n shouldThrow = true,\n }: SimplePriceParams & { useCoingeckoProxy?: boolean }): Promise<SimplePriceResponse> {\n if (useCoingeckoProxy) {\n const rawData = await coingeckoProxyClient(this.#proxyApiUrl).simplePrice(undefined, {\n queries: {\n ids: coinIds?.join(','),\n vs_currencies: currencies.join(','),\n include_market_cap: String(marketCap),\n include_24hr_vol: String(vol24),\n include_24hr_change: String(change24),\n include_last_updated_at: String(lastUpdated),\n },\n });\n return this.transformSimplePriceResponse(rawData, currencies);\n }\n return simplePrice(coingeckoBasicClient, {\n coinIds,\n currencies,\n marketCap,\n vol24,\n change24,\n lastUpdated,\n shouldThrow,\n });\n }\n\n private transformSimplePriceResponse = (\n data: RawSimplePriceResponse,\n currencies = [VsCurrencyType.USD],\n ): SimplePriceResponse => {\n const formattedData: SimplePriceResponse = {};\n Object.keys(data).forEach((id) => {\n const tokenData = data[id];\n formattedData[id] = {};\n currencies.forEach((currency: VsCurrencyType) => {\n formattedData[id] = {\n [currency]: {\n price: tokenData?.[currency],\n change24: tokenData?.[`${currency}_24h_change`],\n vol24: tokenData?.[`${currency}_24h_vol`],\n marketCap: tokenData?.[`${currency}_market_cap`],\n },\n };\n });\n });\n return formattedData;\n };\n}\n","const DEFAULT_MAX_RETRIES = 10;\n\ntype RetryParams<T> = {\n operation: (retryIndex: number) => Promise<T>;\n isSuccess: (result: T) => boolean;\n maxRetries?: number;\n backoffPolicy?: RetryBackoffPolicyInterface;\n};\n/*\n * Retries an operation with defined backoff policy.\n *\n * @param operation - The operation to retry.\n * @param isSuccess - The predicate to check if the operation succeeded.\n * @param maxRetries - The maximum number of retries.\n * @param backoffPolicy - Function to generate delay time based on current retry count.\n *\n * @returns The result of the operation.\n * @throws An error if the operation fails after the maximum number of retries.\n *\n * @example\n * const result = await retry(\n * async () => {\n * const response = await fetch('https://example.com')\n * return response.json()\n * },\n * result => result.status === 200\n * )\n */\nexport const retry = async <T>({\n operation,\n isSuccess,\n maxRetries = DEFAULT_MAX_RETRIES,\n backoffPolicy = RetryBackoffPolicy.exponential(),\n}: RetryParams<T>): Promise<T> => {\n let backoffPeriodMillis = 0;\n let retries = 0;\n let lastError: unknown;\n\n while (retries < maxRetries) {\n if (retries > 0) {\n await delay(backoffPeriodMillis);\n }\n\n try {\n const result = await operation(retries);\n\n if (isSuccess(result)) {\n return result;\n }\n } catch (err) {\n // when the operation throws an error, we still retry\n lastError = err;\n }\n\n backoffPeriodMillis = backoffPolicy(retries);\n retries++;\n }\n\n const errorMessage = lastError ? `Max retry exceeded. ${lastError}` : 'Max retry exceeded.';\n\n throw new Error(errorMessage);\n};\n\ntype RetryBackoffPolicyInterface = (retryIndex: number) => number;\n\nexport class RetryBackoffPolicy {\n static exponential(): RetryBackoffPolicyInterface {\n return (retryIndex: number): number => {\n return Math.pow(2, retryIndex) * 1000;\n };\n }\n\n static constant(secondsToDelay: number): RetryBackoffPolicyInterface {\n return (_: number): number => {\n return secondsToDelay * 1000;\n };\n }\n\n static constantMs(msToDelay: number): RetryBackoffPolicyInterface {\n return (_: number): number => {\n return msToDelay;\n };\n }\n}\n\nfunction delay(ms: number) {\n return new Promise((r) => setTimeout(r, ms));\n}\n","import { RetryBackoffPolicy, retry } from './retry';\n\ntype Error = {\n status: {\n error_code: number;\n error_message: string;\n };\n};\n\nexport const coingeckoRetry = <T>(\n operation: (useCoingeckoProxy: boolean) => Promise<T | Error>,\n): Promise<T | undefined> => {\n return retry({\n operation: (retryIndex: number) => operation(retryIndex > 0),\n maxRetries: 2,\n backoffPolicy: RetryBackoffPolicy.constant(1),\n isSuccess: (response: T | Error) => {\n const errorStatus = (response as Error)?.status;\n return errorStatus?.error_code !== 429;\n },\n }) as Promise<T | undefined>;\n};\n","export function charsum(s: string): number {\n let i,\n sum = 0;\n for (i = 0; i < s.length; i++) {\n sum += s.charCodeAt(i) * (i + 1);\n }\n return sum;\n}\n","import { charsum } from './charsum';\n\n// from https://stackoverflow.com/a/25105589\nexport function arrayHash(array: string[]): string {\n let i,\n sum = 0;\n for (i = 0; i < array.length; i++) {\n const cs = charsum(array[i] ?? '');\n sum = sum + 65027 / cs;\n }\n return ('' + sum).slice(0, 16);\n}\n","import { Zodios } from '@zodios/core';\nimport { RawSimplePriceResponseSchema, SimplePriceResponseSchema } from '@avalabs/vm-module-types';\nimport { boolean, string } from 'zod';\n\nexport const coingeckoProxyClient = (proxyApiUrl: string) =>\n new Zodios(\n `${proxyApiUrl}/proxy/coingecko`,\n [\n {\n method: 'post',\n path: '/simple/price',\n parameters: [\n { name: 'ids', type: 'Query', schema: string() },\n { name: 'vs_currencies', type: 'Query', schema: string() },\n {\n name: 'include_market_cap',\n type: 'Query',\n schema: string().optional(),\n },\n {\n name: 'include_24hr_vol',\n type: 'Query',\n schema: string().optional(),\n },\n {\n name: 'include_24hr_change',\n type: 'Query',\n schema: string().optional(),\n },\n {\n name: 'include_last_updated_at',\n type: 'Query',\n schema: string().optional(),\n },\n ],\n alias: 'simplePrice',\n response: RawSimplePriceResponseSchema,\n },\n {\n method: 'post',\n path: '/simple/token_price/:id',\n parameters: [\n { name: 'id', type: 'Path', schema: string() },\n { name: 'contract_addresses', type: 'Query', schema: string().array() },\n { name: 'vs_currencies', type: 'Query', schema: string().array() },\n {\n name: 'include_market_cap',\n type: 'Query',\n schema: boolean().optional(),\n },\n {\n name: 'include_24hr_vol',\n type: 'Query',\n schema: boolean().optional(),\n },\n {\n name: 'include_24hr_change',\n type: 'Query',\n schema: boolean().optional(),\n },\n ],\n alias: 'simplePriceByContractAddresses',\n response: SimplePriceResponseSchema,\n },\n ],\n {\n axiosConfig: {\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n },\n );\n","import { Zodios } from '@zodios/core';\nimport z, { number, object, record, string } from 'zod';\n\nconst CURRENCY_EXCHANGE_RATES_URL =\n 'https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/usd.min.json';\n\nconst CURRENCY_EXCHANGE_RATES_FALLBACK_URL = 'https://latest.currency-api.pages.dev/v1/currencies/usd.min.json';\n\nconst ExchangeRateSchema = object({\n date: string(),\n usd: record(number()),\n});\n\ntype ExchangeRate = z.infer<typeof ExchangeRateSchema>;\n\nconst exchangeRateApiClient = new Zodios(CURRENCY_EXCHANGE_RATES_URL, [\n {\n method: 'get',\n path: '',\n alias: 'getExchangeRates',\n response: ExchangeRateSchema,\n },\n]);\n\nconst exchangeRateFallbackApiClient = new Zodios(CURRENCY_EXCHANGE_RATES_FALLBACK_URL, [\n {\n method: 'get',\n path: '',\n alias: 'getExchangeRates',\n response: ExchangeRateSchema,\n },\n]);\n\nexport const getExchangeRates = async (): Promise<ExchangeRate> => {\n try {\n return await exchangeRateApiClient.getExchangeRates();\n } catch {\n return await exchangeRateFallbackApiClient.getExchangeRates();\n }\n};\n","import {\n type AddressItem,\n type CurrencyItem,\n type NodeIDItem,\n type TextItem,\n type DataItem,\n type DateItem,\n type LinkItemValue,\n DetailItemType,\n type LinkItem,\n} from '@avalabs/vm-module-types';\n\nexport const currencyItem = (label: string, value: bigint, maxDecimals: number, symbol: string): CurrencyItem => ({\n label,\n type: DetailItemType.CURRENCY,\n value,\n maxDecimals,\n symbol,\n});\n\nexport const textItem = (\n label: string,\n value: string,\n alignment: 'horizontal' | 'vertical' = 'horizontal',\n): TextItem => ({\n label,\n alignment,\n type: DetailItemType.TEXT,\n value,\n});\n\nexport const linkItem = (label: string, value: LinkItemValue): LinkItem => ({\n label,\n value,\n type: DetailItemType.LINK,\n});\n\nexport const addressItem = (label: string, value: string): AddressItem => ({\n label,\n type: DetailItemType.ADDRESS,\n value,\n});\n\nexport const nodeIDItem = (label: string, value: string): NodeIDItem => ({\n label,\n type: DetailItemType.NODE_ID,\n value,\n});\n\nexport const dataItem = (label: string, value: string): DataItem => ({\n label,\n type: DetailItemType.DATA,\n value,\n});\n\nexport const dateItem = (label: string, value: string): DateItem => ({\n label,\n type: DetailItemType.DATE,\n value,\n});\n","import type { SimplePriceResponse, TokenMarketData } from '@avalabs/vm-module-types';\n\nexport const extractTokenMarketData = (\n coinId: string,\n currency?: string,\n data?: SimplePriceResponse,\n): TokenMarketData => {\n const coinData = data?.[coinId]?.[currency ?? ''] ?? {};\n\n return {\n priceInCurrency: coinData.price ?? undefined,\n marketCap: coinData.marketCap ?? undefined,\n vol24: coinData.vol24 ?? undefined,\n change24: coinData.change24 ?? undefined,\n };\n};\n","import type { GetAddressParams, GetAddressResponse } from '@avalabs/vm-module-types';\nimport { getBech32AddressFromXPub, getBtcAddressFromPubKey } from '@avalabs/core-wallets-sdk';\nimport { networks } from 'bitcoinjs-lib';\nimport { NetworkVMType, WalletType } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\n\ntype GetAddress = Omit<GetAddressParams, 'xpubXP'>;\n\nexport const getAddress = async ({\n accountIndex,\n xpub,\n isTestnet,\n walletType,\n}: GetAddress): Promise<GetAddressResponse> => {\n switch (walletType) {\n case WalletType.Mnemonic:\n case WalletType.Ledger:\n case WalletType.Keystone: {\n return {\n [NetworkVMType.BITCOIN]: getBech32AddressFromXPub(\n xpub,\n accountIndex,\n isTestnet ? networks.testnet : networks.bitcoin,\n ),\n };\n }\n case WalletType.LedgerLive:\n case WalletType.Seedless: {\n const pubKeyBuffer = Buffer.from(xpub, 'hex');\n return {\n [NetworkVMType.BITCOIN]: getBtcAddressFromPubKey(pubKeyBuffer, isTestnet ? networks.testnet : networks.bitcoin),\n };\n }\n default:\n throw rpcErrors.invalidParams(`Unsupported wallet type: ${walletType}`);\n }\n};\n","import {\n RpcMethod,\n type ApprovalController,\n type DisplayData,\n type Hex,\n type Network,\n type RpcRequest,\n type SigningData,\n type SigningResult,\n} from '@avalabs/vm-module-types';\nimport { parseRequestParams } from './schema';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { getProvider } from '../../utils/get-provider';\nimport { getBalances } from '../get-balances/get-balances';\nimport { isBtcBalance } from '../../utils/is-btc-balance';\nimport { BitcoinProvider, createTransferTx, type BitcoinInputUTXO } from '@avalabs/core-wallets-sdk';\nimport { calculateGasLimit } from '../../utils/calculate-gas-limit';\nimport { addressItem, currencyItem } from '@internal/utils';\nimport { linkItem } from '@internal/utils/src/utils/detail-item';\n\ntype BitcoinSendTransactionParams = {\n request: RpcRequest;\n network: Network;\n approvalController: ApprovalController;\n proxyApiUrl: string;\n};\n\nexport const bitcoinSendTransaction = async ({\n request,\n network,\n approvalController,\n proxyApiUrl,\n}: BitcoinSendTransactionParams) => {\n const { dappInfo, params: rawParams } = request;\n\n const { success, data: params, error: parseError } = parseRequestParams(rawParams);\n\n if (!success) {\n console.error('invalid params', parseError);\n return {\n error: rpcErrors.invalidParams({ message: 'Transaction params are invalid', data: { cause: parseError } }),\n };\n }\n\n const balances = await getBalances({ addresses: [params.from], network, proxyApiUrl, withScripts: true });\n const btcBalance = balances?.[params.from]?.[network.networkToken.symbol];\n\n if (!isBtcBalance(btcBalance)) {\n return {\n error: rpcErrors.internal('Balance for the source account is not available'),\n };\n }\n\n const provider = getProvider({\n isTestnet: Boolean(network.isTestnet),\n proxyApiUrl,\n });\n\n const { to, from, amount, feeRate } = params;\n\n const { inputs, outputs, fee } = createTransferTx(\n to,\n from,\n amount,\n feeRate,\n btcBalance.utxos as BitcoinInputUTXO[], // we asked for scripts in getBalances() call\n provider.getNetwork(),\n );\n\n if (!inputs || !outputs) {\n return {\n error: rpcErrors.internal('Unable to create transaction'),\n };\n }\n\n const displayData: DisplayData = {\n title: 'Approve Transaction',\n network: {\n chainId: network.chainId,\n name: network.chainName,\n logoUri: network.logoUri,\n },\n details: [\n {\n title: 'Transaction Details',\n items: [\n linkItem('Website', dappInfo),\n addressItem('From', from),\n addressItem('To', to),\n currencyItem('Amount', BigInt(amount), network.networkToken.decimals, network.networkToken.symbol),\n ],\n },\n ],\n networkFeeSelector: true,\n };\n\n const signingData: SigningData = {\n type: RpcMethod.BITCOIN_SEND_TRANSACTION,\n account: from,\n data: {\n to,\n amount,\n fee,\n feeRate,\n gasLimit: calculateGasLimit(fee, feeRate),\n inputs,\n outputs,\n balance: btcBalance,\n },\n };\n\n const response = await approvalController.requestApproval({ request, displayData, signingData });\n\n if ('error' in response) {\n return {\n error: response.error,\n };\n }\n\n let txHash;\n\n try {\n txHash = await getTxHash(provider, response);\n } catch (error) {\n return {\n error: rpcErrors.internal({ message: 'Unable to get transaction hash', data: { cause: error } }),\n };\n }\n\n waitForTransactionReceipt({\n provider,\n txHash: txHash as Hex,\n onTransactionConfirmed: approvalController.onTransactionConfirmed,\n onTransactionReverted: approvalController.onTransactionReverted,\n // Pass the requestId so that client apps can pair the transaction\n // status changes back to their respective requests for better tracking.\n requestId: request.requestId,\n });\n\n return {\n result: txHash,\n };\n};\n\nconst getTxHash = async (provider: BitcoinProvider, response: SigningResult) => {\n if ('txHash' in response) {\n return response.txHash;\n }\n\n return provider.issueRawTx(response.signedData);\n};\n\nconst waitForTransactionReceipt = async ({\n provider,\n txHash,\n onTransactionConfirmed,\n onTransactionReverted,\n requestId,\n}: {\n provider: BitcoinProvider;\n txHash: Hex;\n onTransactionConfirmed: (txHash: Hex, requestId: string) => void;\n onTransactionReverted: (txHash: Hex, requestId: string) => void;\n requestId: string;\n}) => {\n try {\n await provider.waitForTx(txHash);\n onTransactionConfirmed(txHash, requestId);\n } catch (err) {\n console.error(err);\n onTransactionReverted(txHash, requestId);\n }\n};\n","import { z } from 'zod';\n\nconst paramsSchema = z.object({\n from: z.string(),\n to: z.string(),\n amount: z.number(),\n feeRate: z.number(),\n});\n\nexport const parseRequestParams = (params: unknown) => {\n return paramsSchema.safeParse(params);\n};\n\nexport type BitcoinSendTransactionParams = z.infer<typeof paramsSchema>;\n","import type { TokenWithBalance, TokenWithBalanceBTC } from '@avalabs/vm-module-types';\n\nexport const isBtcBalance = (balance?: TokenWithBalance): balance is TokenWithBalanceBTC => {\n if (!balance) {\n return false;\n }\n\n const hasUtxos = 'utxos' in balance; // BTC, P-Chain or X-Chain\n const hasLocked = 'locked' in balance; // X-Chain only\n const hasUnlockedUnstaked = 'unlockedUnstaked' in balance; // P-Chain only\n\n return hasUtxos && !hasUnlockedUnstaked && !hasLocked;\n};\n","// The transaction's byte size is for BTC as gasLimit is for EVM.\n// Bitcoin's formula for fee is `transactionByteLength * feeRate`.\n// Since we know the `fee` and the `feeRate`, we can get the transaction's\n// byte length by division.\nexport const calculateGasLimit = (fee: number, feeRate: number): number => {\n return fee / feeRate;\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@avalabs/bitcoin-module",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "main": "dist/index.cjs",
5
5
  "module": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -11,10 +11,10 @@
11
11
  ],
12
12
  "license": "Limited Ecosystem License",
13
13
  "dependencies": {
14
- "@avalabs/vm-module-types": "0.3.1",
15
- "@avalabs/core-wallets-sdk": "3.1.0-alpha.1",
16
- "@avalabs/core-coingecko-sdk": "3.1.0-alpha.1",
17
- "@avalabs/core-utils-sdk": "3.1.0-alpha.1",
14
+ "@avalabs/vm-module-types": "0.4.1",
15
+ "@avalabs/core-wallets-sdk": "3.1.0-alpha.5",
16
+ "@avalabs/core-coingecko-sdk": "3.1.0-alpha.5",
17
+ "@avalabs/core-utils-sdk": "3.1.0-alpha.5",
18
18
  "@metamask/rpc-errors": "6.3.0",
19
19
  "big.js": "6.2.1",
20
20
  "bn.js": "5.2.1",
@@ -30,7 +30,7 @@
30
30
  "ts-jest": "29.1.1",
31
31
  "tsup": "7.2.0",
32
32
  "@internal/tsup-config": "0.0.1",
33
- "@internal/utils": "0.0.4",
33
+ "@internal/utils": "0.1.0",
34
34
  "eslint-config-custom": "0.0.1"
35
35
  },
36
36
  "scripts": {