@walletconnect/companion-wallet 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -143,40 +143,10 @@ function normalizeTransaction(tx) {
143
143
  // src/rpc.ts
144
144
  import {
145
145
  createWalletClient,
146
- createPublicClient
146
+ createPublicClient,
147
+ formatUnits
147
148
  } from "viem";
148
149
  import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
149
- async function sendTransaction(privateKey, transaction, caip2Chain) {
150
- const chain = resolveChain(caip2Chain);
151
- const transport = getTransport(caip2Chain);
152
- const account = privateKeyToAccount2(privateKey);
153
- const publicClient = createPublicClient({ chain, transport });
154
- const walletClient = createWalletClient({ account, chain, transport });
155
- const normalized = normalizeTransaction(transaction);
156
- const request = {
157
- to: normalized.to,
158
- value: normalized.value,
159
- data: normalized.data,
160
- nonce: normalized.nonce,
161
- gas: normalized.gas,
162
- account,
163
- chain
164
- };
165
- if (!request.gas) {
166
- request.gas = await publicClient.estimateGas({
167
- account: account.address,
168
- to: request.to,
169
- value: request.value,
170
- data: request.data
171
- });
172
- }
173
- const hash = await walletClient.sendTransaction(request);
174
- return hash;
175
- }
176
-
177
- // src/fund.ts
178
- import { parseEther } from "viem";
179
- import { withWallet, resolveProjectId } from "@walletconnect/cli-sdk";
180
150
 
181
151
  // src/tokens.ts
182
152
  import { encodeFunctionData } from "viem";
@@ -185,10 +155,13 @@ var USDC_ADDRESSES = {
185
155
  "eip155:8453": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
186
156
  "eip155:10": "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"
187
157
  };
158
+ var WCT_ADDRESSES = {
159
+ "eip155:10": "0xeF4461891DfB3AC8572cCf7C794664A8DD927945"
160
+ };
188
161
  var TOKEN_REGISTRY = {
189
162
  "eip155:1": ["eth", "usdc"],
190
163
  "eip155:8453": ["eth", "usdc"],
191
- "eip155:10": ["eth", "usdc"]
164
+ "eip155:10": ["eth", "usdc", "wct"]
192
165
  };
193
166
  function getTokenSymbols(chain) {
194
167
  return TOKEN_REGISTRY[chain] ?? ["eth"];
@@ -205,6 +178,13 @@ function getToken(symbol, chain) {
205
178
  }
206
179
  return { symbol: "USDC", decimals: 6, address };
207
180
  }
181
+ if (s === "wct") {
182
+ const address = WCT_ADDRESSES[chain];
183
+ if (!address) {
184
+ throw new Error(`WCT not supported on chain ${chain}`);
185
+ }
186
+ return { symbol: "WCT", decimals: 18, address };
187
+ }
208
188
  throw new Error(`Unknown token: ${symbol}`);
209
189
  }
210
190
  function parseTokenAmount(amount, decimals) {
@@ -233,7 +213,84 @@ function buildErc20Transfer(tokenAddress, to, amount) {
233
213
  return { to: tokenAddress, data, value: "0x0" };
234
214
  }
235
215
 
216
+ // src/rpc.ts
217
+ async function getBalance(address, caip2Chain) {
218
+ const chain = resolveChain(caip2Chain);
219
+ const transport = getTransport(caip2Chain);
220
+ const client = createPublicClient({ chain, transport });
221
+ return client.getBalance({ address });
222
+ }
223
+ var ERC20_BALANCE_OF_ABI = [
224
+ {
225
+ name: "balanceOf",
226
+ type: "function",
227
+ stateMutability: "view",
228
+ inputs: [{ name: "account", type: "address" }],
229
+ outputs: [{ name: "", type: "uint256" }]
230
+ }
231
+ ];
232
+ async function getTokenBalance(address, tokenAddress, caip2Chain) {
233
+ const chain = resolveChain(caip2Chain);
234
+ const transport = getTransport(caip2Chain);
235
+ const client = createPublicClient({ chain, transport });
236
+ return client.readContract({
237
+ address: tokenAddress,
238
+ abi: ERC20_BALANCE_OF_ABI,
239
+ functionName: "balanceOf",
240
+ args: [address]
241
+ });
242
+ }
243
+ async function getBalances(address, caip2Chain) {
244
+ const symbols = getTokenSymbols(caip2Chain);
245
+ const entries = await Promise.all(
246
+ symbols.map(async (sym) => {
247
+ const token = getToken(sym, caip2Chain);
248
+ let raw;
249
+ if (token.address) {
250
+ raw = await getTokenBalance(address, token.address, caip2Chain);
251
+ } else {
252
+ raw = await getBalance(address, caip2Chain);
253
+ }
254
+ return {
255
+ token: token.symbol,
256
+ balance: formatUnits(raw, token.decimals),
257
+ raw: raw.toString()
258
+ };
259
+ })
260
+ );
261
+ return entries;
262
+ }
263
+ async function sendTransaction(privateKey, transaction, caip2Chain) {
264
+ const chain = resolveChain(caip2Chain);
265
+ const transport = getTransport(caip2Chain);
266
+ const account = privateKeyToAccount2(privateKey);
267
+ const publicClient = createPublicClient({ chain, transport });
268
+ const walletClient = createWalletClient({ account, chain, transport });
269
+ const normalized = normalizeTransaction(transaction);
270
+ const request = {
271
+ to: normalized.to,
272
+ value: normalized.value,
273
+ data: normalized.data,
274
+ nonce: normalized.nonce,
275
+ gas: normalized.gas,
276
+ account,
277
+ chain
278
+ };
279
+ if (!request.gas) {
280
+ request.gas = await publicClient.estimateGas({
281
+ account: account.address,
282
+ to: request.to,
283
+ value: request.value,
284
+ data: request.data
285
+ });
286
+ }
287
+ const hash = await walletClient.sendTransaction(request);
288
+ return hash;
289
+ }
290
+
236
291
  // src/fund.ts
292
+ import { parseEther } from "viem";
293
+ import { withWallet, resolveProjectId } from "@walletconnect/cli-sdk";
237
294
  async function fund(options) {
238
295
  const { amount, chain, token: tokenSymbol = "eth" } = options;
239
296
  const embeddedAddress = resolveAccount(options.account);
@@ -680,6 +737,7 @@ async function handleInfo() {
680
737
  "sign-typed-data",
681
738
  "sign-transaction",
682
739
  "send-transaction",
740
+ "balance",
683
741
  "grant-session",
684
742
  "revoke-session",
685
743
  "get-session",
@@ -783,6 +841,35 @@ async function handleSendTransaction() {
783
841
  }
784
842
  respond({ transactionHash });
785
843
  }
844
+ async function handleBalance() {
845
+ let account = parseCliArg("account");
846
+ let chain = parseCliArg("chain");
847
+ const input = await parseInput();
848
+ if (input?.account) account = input.account;
849
+ if (input?.chain) chain = input.chain;
850
+ if (!account) {
851
+ const addresses = listAddresses();
852
+ if (addresses.length === 0) {
853
+ respondError("No wallet found. Run 'generate' first.", "INVALID_INPUT");
854
+ process.exit(ExitCode.ERROR);
855
+ }
856
+ account = addresses[0];
857
+ }
858
+ try {
859
+ if (process.stdin.isTTY && !chain) {
860
+ chain = await selectChain();
861
+ }
862
+ chain = chain || "eip155:10";
863
+ const balances = await getBalances(account, chain);
864
+ respond({ balances });
865
+ } catch (err) {
866
+ respondError(
867
+ err instanceof Error ? err.message : "Balance check failed",
868
+ "BALANCE_ERROR"
869
+ );
870
+ process.exit(ExitCode.ERROR);
871
+ }
872
+ }
786
873
  async function handleGrantSession() {
787
874
  const input = await parseInput();
788
875
  if (!input?.account || !input?.chain || !input?.permissions || !input?.expiry) {
@@ -921,6 +1008,7 @@ var HANDLERS = {
921
1008
  "sign-typed-data": handleSignTypedData,
922
1009
  "sign-transaction": handleSignTransaction,
923
1010
  "send-transaction": handleSendTransaction,
1011
+ balance: handleBalance,
924
1012
  "grant-session": handleGrantSession,
925
1013
  "revoke-session": handleRevokeSession,
926
1014
  "get-session": handleGetSession,
package/dist/index.cjs CHANGED
@@ -1,9 +1,9 @@
1
- "use strict";var L=Object.defineProperty;var Cn=Object.getOwnPropertyDescriptor;var Pn=Object.getOwnPropertyNames;var Hn=Object.prototype.hasOwnProperty;var An=(n,e)=>{for(var t in e)L(n,t,{get:e[t],enumerable:!0})},Fn=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Pn(e))!Hn.call(n,s)&&s!==t&&L(n,s,{get:()=>e[s],enumerable:!(r=Cn(e,s))||r.enumerable});return n};var Nn=n=>Fn(L({},"__esModule",{value:!0}),n);var Wn={};An(Wn,{ExitCode:()=>En,SUPPORTED_CHAINS:()=>C,SessionError:()=>d,buildErc20Transfer:()=>j,drain:()=>wn,fund:()=>xn,generateAndStore:()=>X,getBalance:()=>on,getChainName:()=>U,getToken:()=>v,getTokenSymbols:()=>_,getTransport:()=>w,grantSession:()=>Rn,inputAddress:()=>gn,inputAmount:()=>mn,keyFilePath:()=>E,listAddresses:()=>b,loadKey:()=>D,loadMnemonic:()=>Z,loadSession:()=>F,normalizeTransaction:()=>P,parseChainId:()=>O,parseTokenAmount:()=>G,recordSessionUsage:()=>In,resolveChain:()=>y,revokeSession:()=>vn,selectChain:()=>ln,selectToken:()=>dn,sendTransaction:()=>an,signMessage:()=>en,signTransaction:()=>rn,signTypedData:()=>tn,validateSession:()=>kn});module.exports=Nn(Wn);var p=require("fs"),k=require("path"),Y=require("os"),h=require("viem/accounts"),I=require("viem"),Q=(0,k.join)((0,Y.homedir)(),".config","wallet","keys");function E(n){return(0,k.join)(Q,`${(0,I.getAddress)(n)}.json`)}function X(){let n=(0,h.generateMnemonic)(h.english),e=(0,h.mnemonicToAccount)(n),t=(0,I.getAddress)(e.address),r=E(t);return(0,p.mkdirSync)((0,k.dirname)(r),{recursive:!0,mode:448}),Dn(r,JSON.stringify({version:2,address:t,mnemonic:n},null,2)),{address:t,mnemonic:n}}function D(n){let e=E((0,I.getAddress)(n)),t=(0,p.readFileSync)(e,"utf-8"),r=JSON.parse(t),s=(0,h.mnemonicToAccount)(r.mnemonic);return s.getHdKey().privateKey?`0x${Buffer.from(s.getHdKey().privateKey).toString("hex")}`:(()=>{throw new Error("Failed to derive private key from mnemonic")})()}function Z(n){let e=E((0,I.getAddress)(n)),t=(0,p.readFileSync)(e,"utf-8");return JSON.parse(t).mnemonic}function b(){try{return(0,p.readdirSync)(Q).filter(e=>e.endsWith(".json")).map(e=>e.replace(".json",""))}catch{return[]}}function Dn(n,e){let t=n+".tmp";(0,p.writeFileSync)(t,e,{mode:384}),(0,p.renameSync)(t,n)}var B=require("viem/accounts");var R=require("viem/chains"),nn=require("viem"),$={"eip155:1":{chain:R.mainnet,name:"Ethereum",defaultRpcUrl:"https://eth.drpc.org"},"eip155:8453":{chain:R.base,name:"Base",defaultRpcUrl:"https://mainnet.base.org"},"eip155:10":{chain:R.optimism,name:"Optimism",defaultRpcUrl:"https://mainnet.optimism.io"}},C=Object.keys($);function y(n){let e=$[n];if(!e)throw new Error(`Unsupported chain: ${n}. Supported: ${C.join(", ")}`);return e.chain}function w(n){let e=$[n];if(!e)throw new Error(`Unsupported chain: ${n}`);let t=n.split(":")[1],r=process.env[`WALLET_RPC_URL_${t}`];return(0,nn.http)(r||e.defaultRpcUrl)}function O(n){let e=n.split(":");if(e.length!==2||e[0]!=="eip155")throw new Error(`Invalid CAIP-2 chain ID: ${n}`);return parseInt(e[1],10)}function U(n){let e=$[n];if(!e)throw new Error(`Unsupported chain: ${n}`);return e.name}async function en(n,e){return(0,B.privateKeyToAccount)(n).signMessage({message:e})}async function tn(n,e){return(0,B.privateKeyToAccount)(n).signTypedData(e)}async function rn(n,e,t){let r=(0,B.privateKeyToAccount)(n),s=O(t),i={...P(e),chainId:s};return!e.type&&!e.gasPrice&&!e.maxFeePerGas&&!e.accessList&&!e.blobs&&!e.authorizationList&&(i.type="eip1559"),r.signTransaction(i)}function P(n){return{to:n.to,value:n.value!==void 0?BigInt(n.value):void 0,data:n.data,nonce:n.nonce!==void 0?Number(n.nonce):void 0,gas:n.gas!==void 0?BigInt(n.gas):void 0,gasPrice:n.gasPrice!==void 0?BigInt(n.gasPrice):void 0,maxFeePerGas:n.maxFeePerGas!==void 0?BigInt(n.maxFeePerGas):void 0,maxPriorityFeePerGas:n.maxPriorityFeePerGas!==void 0?BigInt(n.maxPriorityFeePerGas):void 0}}var H=require("viem"),sn=require("viem/accounts");async function on(n,e){let t=y(e),r=w(e);return(0,H.createPublicClient)({chain:t,transport:r}).getBalance({address:n})}async function an(n,e,t){let r=y(t),s=w(t),o=(0,sn.privateKeyToAccount)(n),i=(0,H.createPublicClient)({chain:r,transport:s}),a=(0,H.createWalletClient)({account:o,chain:r,transport:s}),l=P(e),c={to:l.to,value:l.value,data:l.data,nonce:l.nonce,gas:l.gas,account:o,chain:r};return c.gas||(c.gas=await i.estimateGas({account:o.address,to:c.to,value:c.value,data:c.data})),await a.sendTransaction(c)}var cn=require("viem"),$n={"eip155:1":"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","eip155:8453":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","eip155:10":"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"},On={"eip155:1":["eth","usdc"],"eip155:8453":["eth","usdc"],"eip155:10":["eth","usdc"]};function _(n){return On[n]??["eth"]}function v(n,e){let t=n.toLowerCase();if(t==="eth")return{symbol:"ETH",decimals:18};if(t==="usdc"){let r=$n[e];if(!r)throw new Error(`USDC not supported on chain ${e}`);return{symbol:"USDC",decimals:6,address:r}}throw new Error(`Unknown token: ${n}`)}function G(n,e){let[t="0",r=""]=n.split("."),s=r.padEnd(e,"0").slice(0,e);return BigInt(t)*10n**BigInt(e)+BigInt(s)}var Un=[{name:"transfer",type:"function",stateMutability:"nonpayable",inputs:[{name:"to",type:"address"},{name:"amount",type:"uint256"}],outputs:[{name:"",type:"bool"}]}];function j(n,e,t){let r=(0,cn.encodeFunctionData)({abi:Un,functionName:"transfer",args:[e,t]});return{to:n,data:r,value:"0x0"}}var un=require("readline/promises"),W=require("process");async function K(n){let e=(0,un.createInterface)({input:W.stdin,output:W.stdout});try{return(await e.question(n)).trim()}finally{e.close()}}function pn(n){for(let e=0;e<n.length;e++)process.stderr.write(` ${e+1}. ${n[e].label}
2
- `)}async function ln(){let n=C.map(r=>({label:U(r),value:r}));process.stderr.write(`
1
+ "use strict";var L=Object.defineProperty;var Hn=Object.getOwnPropertyDescriptor;var An=Object.getOwnPropertyNames;var Fn=Object.prototype.hasOwnProperty;var Nn=(n,e)=>{for(var t in e)L(n,t,{get:e[t],enumerable:!0})},Dn=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of An(e))!Fn.call(n,s)&&s!==t&&L(n,s,{get:()=>e[s],enumerable:!(r=Hn(e,s))||r.enumerable});return n};var Bn=n=>Dn(L({},"__esModule",{value:!0}),n);var zn={};Nn(zn,{ExitCode:()=>Pn,SUPPORTED_CHAINS:()=>H,SessionError:()=>d,buildErc20Transfer:()=>j,drain:()=>Tn,fund:()=>Sn,generateAndStore:()=>nn,getBalance:()=>J,getBalances:()=>un,getChainName:()=>U,getToken:()=>x,getTokenBalance:()=>q,getTokenSymbols:()=>I,getTransport:()=>f,grantSession:()=>En,inputAddress:()=>xn,inputAmount:()=>fn,keyFilePath:()=>P,listAddresses:()=>k,loadKey:()=>B,loadMnemonic:()=>en,loadSession:()=>N,normalizeTransaction:()=>A,parseChainId:()=>$,parseTokenAmount:()=>W,recordSessionUsage:()=>Cn,resolveChain:()=>g,revokeSession:()=>In,selectChain:()=>mn,selectToken:()=>gn,sendTransaction:()=>ln,signMessage:()=>rn,signTransaction:()=>on,signTypedData:()=>sn,validateSession:()=>vn});module.exports=Bn(zn);var l=require("fs"),v=require("path"),X=require("os"),T=require("viem/accounts"),C=require("viem"),Z=(0,v.join)((0,X.homedir)(),".config","wallet","keys");function P(n){return(0,v.join)(Z,`${(0,C.getAddress)(n)}.json`)}function nn(){let n=(0,T.generateMnemonic)(T.english),e=(0,T.mnemonicToAccount)(n),t=(0,C.getAddress)(e.address),r=P(t);return(0,l.mkdirSync)((0,v.dirname)(r),{recursive:!0,mode:448}),On(r,JSON.stringify({version:2,address:t,mnemonic:n},null,2)),{address:t,mnemonic:n}}function B(n){let e=P((0,C.getAddress)(n)),t=(0,l.readFileSync)(e,"utf-8"),r=JSON.parse(t),s=(0,T.mnemonicToAccount)(r.mnemonic);return s.getHdKey().privateKey?`0x${Buffer.from(s.getHdKey().privateKey).toString("hex")}`:(()=>{throw new Error("Failed to derive private key from mnemonic")})()}function en(n){let e=P((0,C.getAddress)(n)),t=(0,l.readFileSync)(e,"utf-8");return JSON.parse(t).mnemonic}function k(){try{return(0,l.readdirSync)(Z).filter(e=>e.endsWith(".json")).map(e=>e.replace(".json",""))}catch{return[]}}function On(n,e){let t=n+".tmp";(0,l.writeFileSync)(t,e,{mode:384}),(0,l.renameSync)(t,n)}var _=require("viem/accounts");var E=require("viem/chains"),tn=require("viem"),O={"eip155:1":{chain:E.mainnet,name:"Ethereum",defaultRpcUrl:"https://eth.drpc.org"},"eip155:8453":{chain:E.base,name:"Base",defaultRpcUrl:"https://mainnet.base.org"},"eip155:10":{chain:E.optimism,name:"Optimism",defaultRpcUrl:"https://mainnet.optimism.io"}},H=Object.keys(O);function g(n){let e=O[n];if(!e)throw new Error(`Unsupported chain: ${n}. Supported: ${H.join(", ")}`);return e.chain}function f(n){let e=O[n];if(!e)throw new Error(`Unsupported chain: ${n}`);let t=n.split(":")[1],r=process.env[`WALLET_RPC_URL_${t}`];return(0,tn.http)(r||e.defaultRpcUrl)}function $(n){let e=n.split(":");if(e.length!==2||e[0]!=="eip155")throw new Error(`Invalid CAIP-2 chain ID: ${n}`);return parseInt(e[1],10)}function U(n){let e=O[n];if(!e)throw new Error(`Unsupported chain: ${n}`);return e.name}async function rn(n,e){return(0,_.privateKeyToAccount)(n).signMessage({message:e})}async function sn(n,e){return(0,_.privateKeyToAccount)(n).signTypedData(e)}async function on(n,e,t){let r=(0,_.privateKeyToAccount)(n),s=$(t),i={...A(e),chainId:s};return!e.type&&!e.gasPrice&&!e.maxFeePerGas&&!e.accessList&&!e.blobs&&!e.authorizationList&&(i.type="eip1559"),r.signTransaction(i)}function A(n){return{to:n.to,value:n.value!==void 0?BigInt(n.value):void 0,data:n.data,nonce:n.nonce!==void 0?Number(n.nonce):void 0,gas:n.gas!==void 0?BigInt(n.gas):void 0,gasPrice:n.gasPrice!==void 0?BigInt(n.gasPrice):void 0,maxFeePerGas:n.maxFeePerGas!==void 0?BigInt(n.maxFeePerGas):void 0,maxPriorityFeePerGas:n.maxPriorityFeePerGas!==void 0?BigInt(n.maxPriorityFeePerGas):void 0}}var y=require("viem"),cn=require("viem/accounts");var an=require("viem"),$n={"eip155:1":"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","eip155:8453":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","eip155:10":"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"},Un={"eip155:10":"0xeF4461891DfB3AC8572cCf7C794664A8DD927945"},_n={"eip155:1":["eth","usdc"],"eip155:8453":["eth","usdc"],"eip155:10":["eth","usdc","wct"]};function I(n){return _n[n]??["eth"]}function x(n,e){let t=n.toLowerCase();if(t==="eth")return{symbol:"ETH",decimals:18};if(t==="usdc"){let r=$n[e];if(!r)throw new Error(`USDC not supported on chain ${e}`);return{symbol:"USDC",decimals:6,address:r}}if(t==="wct"){let r=Un[e];if(!r)throw new Error(`WCT not supported on chain ${e}`);return{symbol:"WCT",decimals:18,address:r}}throw new Error(`Unknown token: ${n}`)}function W(n,e){let[t="0",r=""]=n.split("."),s=r.padEnd(e,"0").slice(0,e);return BigInt(t)*10n**BigInt(e)+BigInt(s)}var Wn=[{name:"transfer",type:"function",stateMutability:"nonpayable",inputs:[{name:"to",type:"address"},{name:"amount",type:"uint256"}],outputs:[{name:"",type:"bool"}]}];function j(n,e,t){let r=(0,an.encodeFunctionData)({abi:Wn,functionName:"transfer",args:[e,t]});return{to:n,data:r,value:"0x0"}}async function J(n,e){let t=g(e),r=f(e);return(0,y.createPublicClient)({chain:t,transport:r}).getBalance({address:n})}var jn=[{name:"balanceOf",type:"function",stateMutability:"view",inputs:[{name:"account",type:"address"}],outputs:[{name:"",type:"uint256"}]}];async function q(n,e,t){let r=g(t),s=f(t);return(0,y.createPublicClient)({chain:r,transport:s}).readContract({address:e,abi:jn,functionName:"balanceOf",args:[n]})}async function un(n,e){let t=I(e);return await Promise.all(t.map(async s=>{let o=x(s,e),i;return o.address?i=await q(n,o.address,e):i=await J(n,e),{token:o.symbol,balance:(0,y.formatUnits)(i,o.decimals),raw:i.toString()}}))}async function ln(n,e,t){let r=g(t),s=f(t),o=(0,cn.privateKeyToAccount)(n),i=(0,y.createPublicClient)({chain:r,transport:s}),a=(0,y.createWalletClient)({account:o,chain:r,transport:s}),p=A(e),c={to:p.to,value:p.value,data:p.data,nonce:p.nonce,gas:p.gas,account:o,chain:r};return c.gas||(c.gas=await i.estimateGas({account:o.address,to:c.to,value:c.value,data:c.data})),await a.sendTransaction(c)}var pn=require("readline/promises"),G=require("process");async function K(n){let e=(0,pn.createInterface)({input:G.stdin,output:G.stdout});try{return(await e.question(n)).trim()}finally{e.close()}}function dn(n){for(let e=0;e<n.length;e++)process.stderr.write(` ${e+1}. ${n[e].label}
2
+ `)}async function mn(){let n=H.map(r=>({label:U(r),value:r}));process.stderr.write(`
3
3
  Select chain:
4
- `),pn(n);let e=await K("> "),t=parseInt(e,10)-1;if(isNaN(t)||t<0||t>=n.length)throw new Error(`Invalid selection: ${e}`);return n[t].value}async function dn(n){let t=_(n).map(o=>({label:o.toUpperCase(),value:o}));process.stderr.write(`
4
+ `),dn(n);let e=await K("> "),t=parseInt(e,10)-1;if(isNaN(t)||t<0||t>=n.length)throw new Error(`Invalid selection: ${e}`);return n[t].value}async function gn(n){let t=I(n).map(o=>({label:o.toUpperCase(),value:o}));process.stderr.write(`
5
5
  Select token:
6
- `),pn(t);let r=await K("> "),s=parseInt(r,10)-1;if(isNaN(s)||s<0||s>=t.length)throw new Error(`Invalid selection: ${r}`);return t[s].value}async function mn(n){let e=await K(`
7
- Amount (${n.toUpperCase()}): `),t=parseFloat(e);if(isNaN(t)||t<=0)throw new Error(`Invalid amount: ${e}`);return e}async function gn(n){let e=await K(`
8
- ${n}: `);if(!/^0x[0-9a-fA-F]{40}$/.test(e))throw new Error(`Invalid address: ${e}`);return e}var fn=require("viem"),M=require("@walletconnect/cli-sdk");async function xn(n){let{amount:e,chain:t,token:r="eth"}=n,s=Bn(n.account),o=v(r,t),i=(0,M.resolveProjectId)();if(!i)throw new Error("WalletConnect project ID not found. Set WALLETCONNECT_PROJECT_ID env var.");let a;if(await(0,M.withWallet)({projectId:i,metadata:{name:"companion-wallet",description:"Fund companion wallet",url:"https://walletconnect.com",icons:[]},chains:[t],methods:["eth_sendTransaction"],events:[]},async(l,{accounts:c})=>{let f=c.find(u=>u.startsWith(`${t}:`));if(!f)throw new Error(`No account found on chain ${t}. Connected accounts: ${c.join(", ")}`);let T=f.split(":").slice(2).join(":"),x;if(o.address){let u=G(e,o.decimals),S=j(o.address,s,u);x={from:T,...S}}else{let S=`0x${(0,fn.parseEther)(e).toString(16)}`;x={from:T,to:s,value:S,gas:"0x5208"}}a={transactionHash:await l.request({chainId:t,request:{method:"eth_sendTransaction",params:[x]}}),from:T,to:s,amount:e,token:o.symbol}}),!a)throw new Error("Fund operation completed without a result");return a}function Bn(n){if(n)return n;let e=b();if(e.length===0)throw new Error("No wallet found. Run 'companion-wallet generate' first.");return e[0]}var m=require("viem"),yn=require("viem/accounts");var Sn=21000n,hn=[{name:"balanceOf",type:"function",stateMutability:"view",inputs:[{name:"account",type:"address"}],outputs:[{name:"",type:"uint256"}]},{name:"transfer",type:"function",stateMutability:"nonpayable",inputs:[{name:"to",type:"address"},{name:"amount",type:"uint256"}],outputs:[{name:"",type:"bool"}]}];async function wn(n){let{to:e,chain:t,token:r="eth"}=n,s=v(r,t),o=_n(n.account),i=D(o),a=(0,yn.privateKeyToAccount)(i),l=y(t),c=w(t),f=(0,m.createPublicClient)({chain:l,transport:c}),T=(0,m.createWalletClient)({account:a,chain:l,transport:c}),x,N;if(s.address){let u=await f.readContract({address:s.address,abi:hn,functionName:"balanceOf",args:[a.address]});if(u===0n)throw new Error(`No ${s.symbol} balance to drain`);let S=(0,m.encodeFunctionData)({abi:hn,functionName:"transfer",args:[e,u]});x=await T.sendTransaction({to:s.address,data:S,value:0n}),N=u.toString()}else{let u=await f.getBalance({address:a.address}),S=await f.getGasPrice(),q=Sn*S,z=u-q;if(z<=0n)throw new Error(`Insufficient balance to cover gas. Balance: ${(0,m.formatEther)(u)} ETH, gas cost: ${(0,m.formatEther)(q)} ETH`);x=await T.sendTransaction({to:e,value:z,gas:Sn}),N=z.toString()}return{transactionHash:x,from:a.address,to:e,amount:N,token:s.symbol}}function _n(n){if(n)return n;let e=b();if(e.length===0)throw new Error("No wallet found. Run 'companion-wallet generate' first.");return e[0]}var Tn=require("crypto"),g=require("fs"),A=require("path"),bn=require("os"),Gn=(0,A.join)((0,bn.homedir)(),".config","wallet","sessions");function V(n){return(0,A.join)(Gn,`${n}.json`)}function J(n,e){let t=n+".tmp";(0,g.mkdirSync)((0,A.dirname)(n),{recursive:!0,mode:448}),(0,g.writeFileSync)(t,e,{mode:384}),(0,g.renameSync)(t,n)}function Rn(n){let e=(0,Tn.randomBytes)(16).toString("hex"),t={sessionId:e,account:n.account,chain:n.chain,permissions:n.permissions,expiry:n.expiry,revoked:!1,callCounts:{},totalValue:{}};return J(V(e),JSON.stringify(t,null,2)),t}function vn(n){let e=F(n);e.revoked=!0,J(V(n),JSON.stringify(e,null,2))}function F(n){let e=V(n);try{let t=(0,g.readFileSync)(e,"utf-8");return JSON.parse(t)}catch{throw new Error(`Session not found: ${n}`)}}function kn(n,e,t){let r=F(n);if(r.revoked)throw new d("Session has been revoked");if(Date.now()>r.expiry)throw new d("Session has expired");let s=r.permissions.find(o=>o.operation===e);if(!s)throw new d(`Session does not permit operation: ${e}`);if(s.policies)for(let o of s.policies)jn(o,r,t);return r}function In(n,e,t){let r=F(n),s=e;if(r.callCounts[s]=(r.callCounts[s]||0)+1,t?.transaction?.value){let o=t.chain||"unknown",i=BigInt(r.totalValue[o]||"0"),a=BigInt(t.transaction.value);r.totalValue[o]=(i+a).toString()}J(V(n),JSON.stringify(r,null,2))}function jn(n,e,t){switch(n.type){case"value-limit":{if(!t)break;let r=t.transaction;if(!r?.value)break;let s=t.chain||"unknown",o=BigInt(n.params.maxValue),i=BigInt(e.totalValue[s]||"0"),a=BigInt(r.value);if(i+a>o)throw new d(`Value limit exceeded: ${(i+a).toString()} > ${o.toString()}`);break}case"recipient-allowlist":{if(!t)break;let r=t.transaction;if(!r?.to)break;let s=n.params.addresses.map(i=>i.toLowerCase()),o=r.to.toLowerCase();if(!s.includes(o))throw new d(`Recipient ${r.to} not in allowlist`);break}case"call-limit":{let r=n.params.maxCalls,s=n.params.operation,o=e.callCounts[s]||0;if(o>=r)throw new d(`Call limit reached for ${s}: ${o} >= ${r}`);break}}}var d=class extends Error{constructor(e){super(e),this.name="SessionError"}};var En={SUCCESS:0,ERROR:1,UNSUPPORTED:2,REJECTED:3,TIMEOUT:4,NOT_CONNECTED:5,SESSION_ERROR:6};0&&(module.exports={ExitCode,SUPPORTED_CHAINS,SessionError,buildErc20Transfer,drain,fund,generateAndStore,getBalance,getChainName,getToken,getTokenSymbols,getTransport,grantSession,inputAddress,inputAmount,keyFilePath,listAddresses,loadKey,loadMnemonic,loadSession,normalizeTransaction,parseChainId,parseTokenAmount,recordSessionUsage,resolveChain,revokeSession,selectChain,selectToken,sendTransaction,signMessage,signTransaction,signTypedData,validateSession});
6
+ `),dn(t);let r=await K("> "),s=parseInt(r,10)-1;if(isNaN(s)||s<0||s>=t.length)throw new Error(`Invalid selection: ${r}`);return t[s].value}async function fn(n){let e=await K(`
7
+ Amount (${n.toUpperCase()}): `),t=parseFloat(e);if(isNaN(t)||t<=0)throw new Error(`Invalid amount: ${e}`);return e}async function xn(n){let e=await K(`
8
+ ${n}: `);if(!/^0x[0-9a-fA-F]{40}$/.test(e))throw new Error(`Invalid address: ${e}`);return e}var yn=require("viem"),M=require("@walletconnect/cli-sdk");async function Sn(n){let{amount:e,chain:t,token:r="eth"}=n,s=Gn(n.account),o=x(r,t),i=(0,M.resolveProjectId)();if(!i)throw new Error("WalletConnect project ID not found. Set WALLETCONNECT_PROJECT_ID env var.");let a;if(await(0,M.withWallet)({projectId:i,metadata:{name:"companion-wallet",description:"Fund companion wallet",url:"https://walletconnect.com",icons:[]},chains:[t],methods:["eth_sendTransaction"],events:[]},async(p,{accounts:c})=>{let h=c.find(u=>u.startsWith(`${t}:`));if(!h)throw new Error(`No account found on chain ${t}. Connected accounts: ${c.join(", ")}`);let R=h.split(":").slice(2).join(":"),w;if(o.address){let u=W(e,o.decimals),b=j(o.address,s,u);w={from:R,...b}}else{let b=`0x${(0,yn.parseEther)(e).toString(16)}`;w={from:R,to:s,value:b,gas:"0x5208"}}a={transactionHash:await p.request({chainId:t,request:{method:"eth_sendTransaction",params:[w]}}),from:R,to:s,amount:e,token:o.symbol}}),!a)throw new Error("Fund operation completed without a result");return a}function Gn(n){if(n)return n;let e=k();if(e.length===0)throw new Error("No wallet found. Run 'companion-wallet generate' first.");return e[0]}var m=require("viem"),bn=require("viem/accounts");var hn=21000n,wn=[{name:"balanceOf",type:"function",stateMutability:"view",inputs:[{name:"account",type:"address"}],outputs:[{name:"",type:"uint256"}]},{name:"transfer",type:"function",stateMutability:"nonpayable",inputs:[{name:"to",type:"address"},{name:"amount",type:"uint256"}],outputs:[{name:"",type:"bool"}]}];async function Tn(n){let{to:e,chain:t,token:r="eth"}=n,s=x(r,t),o=Kn(n.account),i=B(o),a=(0,bn.privateKeyToAccount)(i),p=g(t),c=f(t),h=(0,m.createPublicClient)({chain:p,transport:c}),R=(0,m.createWalletClient)({account:a,chain:p,transport:c}),w,D;if(s.address){let u=await h.readContract({address:s.address,abi:wn,functionName:"balanceOf",args:[a.address]});if(u===0n)throw new Error(`No ${s.symbol} balance to drain`);let b=(0,m.encodeFunctionData)({abi:wn,functionName:"transfer",args:[e,u]});w=await R.sendTransaction({to:s.address,data:b,value:0n}),D=u.toString()}else{let u=await h.getBalance({address:a.address}),b=await h.getGasPrice(),Q=hn*b,z=u-Q;if(z<=0n)throw new Error(`Insufficient balance to cover gas. Balance: ${(0,m.formatEther)(u)} ETH, gas cost: ${(0,m.formatEther)(Q)} ETH`);w=await R.sendTransaction({to:e,value:z,gas:hn}),D=z.toString()}return{transactionHash:w,from:a.address,to:e,amount:D,token:s.symbol}}function Kn(n){if(n)return n;let e=k();if(e.length===0)throw new Error("No wallet found. Run 'companion-wallet generate' first.");return e[0]}var Rn=require("crypto"),S=require("fs"),F=require("path"),kn=require("os"),Mn=(0,F.join)((0,kn.homedir)(),".config","wallet","sessions");function V(n){return(0,F.join)(Mn,`${n}.json`)}function Y(n,e){let t=n+".tmp";(0,S.mkdirSync)((0,F.dirname)(n),{recursive:!0,mode:448}),(0,S.writeFileSync)(t,e,{mode:384}),(0,S.renameSync)(t,n)}function En(n){let e=(0,Rn.randomBytes)(16).toString("hex"),t={sessionId:e,account:n.account,chain:n.chain,permissions:n.permissions,expiry:n.expiry,revoked:!1,callCounts:{},totalValue:{}};return Y(V(e),JSON.stringify(t,null,2)),t}function In(n){let e=N(n);e.revoked=!0,Y(V(n),JSON.stringify(e,null,2))}function N(n){let e=V(n);try{let t=(0,S.readFileSync)(e,"utf-8");return JSON.parse(t)}catch{throw new Error(`Session not found: ${n}`)}}function vn(n,e,t){let r=N(n);if(r.revoked)throw new d("Session has been revoked");if(Date.now()>r.expiry)throw new d("Session has expired");let s=r.permissions.find(o=>o.operation===e);if(!s)throw new d(`Session does not permit operation: ${e}`);if(s.policies)for(let o of s.policies)Vn(o,r,t);return r}function Cn(n,e,t){let r=N(n),s=e;if(r.callCounts[s]=(r.callCounts[s]||0)+1,t?.transaction?.value){let o=t.chain||"unknown",i=BigInt(r.totalValue[o]||"0"),a=BigInt(t.transaction.value);r.totalValue[o]=(i+a).toString()}Y(V(n),JSON.stringify(r,null,2))}function Vn(n,e,t){switch(n.type){case"value-limit":{if(!t)break;let r=t.transaction;if(!r?.value)break;let s=t.chain||"unknown",o=BigInt(n.params.maxValue),i=BigInt(e.totalValue[s]||"0"),a=BigInt(r.value);if(i+a>o)throw new d(`Value limit exceeded: ${(i+a).toString()} > ${o.toString()}`);break}case"recipient-allowlist":{if(!t)break;let r=t.transaction;if(!r?.to)break;let s=n.params.addresses.map(i=>i.toLowerCase()),o=r.to.toLowerCase();if(!s.includes(o))throw new d(`Recipient ${r.to} not in allowlist`);break}case"call-limit":{let r=n.params.maxCalls,s=n.params.operation,o=e.callCounts[s]||0;if(o>=r)throw new d(`Call limit reached for ${s}: ${o} >= ${r}`);break}}}var d=class extends Error{constructor(e){super(e),this.name="SessionError"}};var Pn={SUCCESS:0,ERROR:1,UNSUPPORTED:2,REJECTED:3,TIMEOUT:4,NOT_CONNECTED:5,SESSION_ERROR:6};0&&(module.exports={ExitCode,SUPPORTED_CHAINS,SessionError,buildErc20Transfer,drain,fund,generateAndStore,getBalance,getBalances,getChainName,getToken,getTokenBalance,getTokenSymbols,getTransport,grantSession,inputAddress,inputAmount,keyFilePath,listAddresses,loadKey,loadMnemonic,loadSession,normalizeTransaction,parseChainId,parseTokenAmount,recordSessionUsage,resolveChain,revokeSession,selectChain,selectToken,sendTransaction,signMessage,signTransaction,signTypedData,validateSession});
9
9
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/keystore.ts","../src/signer.ts","../src/chains.ts","../src/rpc.ts","../src/tokens.ts","../src/prompt.ts","../src/fund.ts","../src/drain.ts","../src/sessions.ts","../src/types.ts"],"sourcesContent":["export { generateAndStore, loadKey, loadMnemonic, listAddresses, keyFilePath } from \"./keystore.js\";\nexport { signMessage, signTypedData, signTransaction, normalizeTransaction } from \"./signer.js\";\nexport { sendTransaction, getBalance } from \"./rpc.js\";\nexport { resolveChain, getTransport, parseChainId, getChainName, SUPPORTED_CHAINS } from \"./chains.js\";\nexport { getToken, getTokenSymbols, parseTokenAmount, buildErc20Transfer } from \"./tokens.js\";\nexport type { TokenInfo } from \"./tokens.js\";\nexport { selectChain, selectToken, inputAmount, inputAddress } from \"./prompt.js\";\nexport { fund } from \"./fund.js\";\nexport type { FundOptions, FundResult } from \"./fund.js\";\nexport { drain } from \"./drain.js\";\nexport type { DrainOptions, DrainResult } from \"./drain.js\";\nexport {\n grantSession,\n revokeSession,\n loadSession,\n validateSession,\n recordSessionUsage,\n SessionError,\n} from \"./sessions.js\";\nexport { ExitCode } from \"./types.js\";\nexport type {\n Operation,\n InfoResponse,\n AccountsResponse,\n AccountEntry,\n SignMessageInput,\n SignTypedDataInput,\n SignTransactionInput,\n SendTransactionInput,\n SignatureResponse,\n SignedTransactionResponse,\n TransactionHashResponse,\n GrantSessionInput,\n GrantSessionResponse,\n RevokeSessionInput,\n RevokeSessionResponse,\n GetSessionInput,\n SessionState,\n SessionPermission,\n SessionPolicy,\n WalletFile,\n ErrorResponse,\n} from \"./types.js\";\n","import { mkdirSync, writeFileSync, readFileSync, readdirSync, renameSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { generateMnemonic, mnemonicToAccount, english } from \"viem/accounts\";\nimport { getAddress, type Hex } from \"viem\";\nimport type { WalletFile } from \"./types.js\";\n\nconst KEYS_DIR = join(homedir(), \".config\", \"wallet\", \"keys\");\n\n/**\n * Get the path to a key file by address.\n */\nexport function keyFilePath(address: string): string {\n return join(KEYS_DIR, `${getAddress(address)}.json`);\n}\n\n/**\n * Generate a new wallet (BIP-39 mnemonic) and save it to disk.\n * Returns the checksummed address and the mnemonic for backup.\n */\nexport function generateAndStore(): { address: string; mnemonic: string } {\n const mnemonic = generateMnemonic(english);\n const account = mnemonicToAccount(mnemonic);\n const address = getAddress(account.address);\n const filePath = keyFilePath(address);\n\n mkdirSync(dirname(filePath), { recursive: true, mode: 0o700 });\n\n const walletFile: WalletFile = {\n version: 2,\n address,\n mnemonic,\n };\n atomicWrite(filePath, JSON.stringify(walletFile, null, 2));\n\n return { address, mnemonic };\n}\n\n/**\n * Load a private key from disk by deriving it from the stored mnemonic.\n */\nexport function loadKey(address: string): Hex {\n const filePath = keyFilePath(getAddress(address));\n const raw = readFileSync(filePath, \"utf-8\");\n const data = JSON.parse(raw) as WalletFile;\n\n const account = mnemonicToAccount(data.mnemonic);\n return account.getHdKey().privateKey\n ? (`0x${Buffer.from(account.getHdKey().privateKey!).toString(\"hex\")}` as Hex)\n : (() => { throw new Error(\"Failed to derive private key from mnemonic\"); })();\n}\n\n/**\n * Load the mnemonic for an address.\n */\nexport function loadMnemonic(address: string): string {\n const filePath = keyFilePath(getAddress(address));\n const raw = readFileSync(filePath, \"utf-8\");\n const data = JSON.parse(raw) as WalletFile;\n return data.mnemonic;\n}\n\n/**\n * List all stored addresses.\n */\nexport function listAddresses(): string[] {\n try {\n const files = readdirSync(KEYS_DIR);\n return files\n .filter((f) => f.endsWith(\".json\"))\n .map((f) => f.replace(\".json\", \"\"));\n } catch {\n return [];\n }\n}\n\n/**\n * Atomic write: write to .tmp file then rename.\n */\nfunction atomicWrite(filePath: string, content: string): void {\n const tmpPath = filePath + \".tmp\";\n writeFileSync(tmpPath, content, { mode: 0o600 });\n renameSync(tmpPath, filePath);\n}\n","import { privateKeyToAccount } from \"viem/accounts\";\nimport type { Hex, TransactionSerializable } from \"viem\";\nimport { parseChainId } from \"./chains.js\";\n\n/**\n * Sign a plaintext message.\n */\nexport async function signMessage(\n privateKey: Hex,\n message: string,\n): Promise<Hex> {\n const account = privateKeyToAccount(privateKey);\n return account.signMessage({ message });\n}\n\n/**\n * Sign EIP-712 typed data.\n */\nexport async function signTypedData(\n privateKey: Hex,\n typedData: {\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n primaryType: string;\n message: Record<string, unknown>;\n },\n): Promise<Hex> {\n const account = privateKeyToAccount(privateKey);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return account.signTypedData(typedData as any);\n}\n\n/**\n * Sign a transaction (does not broadcast).\n */\nexport async function signTransaction(\n privateKey: Hex,\n transaction: Record<string, unknown>,\n caip2Chain: string,\n): Promise<Hex> {\n const account = privateKeyToAccount(privateKey);\n const chainId = parseChainId(caip2Chain);\n\n const normalized = normalizeTransaction(transaction);\n const tx: TransactionSerializable = {\n ...normalized,\n chainId,\n };\n\n // Default to EIP-1559 if no type or gas pricing fields are provided\n if (!transaction.type && !transaction.gasPrice && !transaction.maxFeePerGas && !transaction.accessList && !transaction.blobs && !transaction.authorizationList) {\n (tx as Record<string, unknown>).type = \"eip1559\";\n }\n\n return account.signTransaction(tx);\n}\n\n/**\n * Normalize transaction fields from JSON input to viem types.\n */\nexport function normalizeTransaction(\n tx: Record<string, unknown>,\n): TransactionSerializable {\n return {\n to: tx.to as Hex | undefined,\n value: tx.value !== undefined ? BigInt(tx.value as string | number) : undefined,\n data: tx.data as Hex | undefined,\n nonce: tx.nonce !== undefined ? Number(tx.nonce) : undefined,\n gas: tx.gas !== undefined ? BigInt(tx.gas as string | number) : undefined,\n gasPrice: tx.gasPrice !== undefined ? BigInt(tx.gasPrice as string | number) : undefined,\n maxFeePerGas: tx.maxFeePerGas !== undefined ? BigInt(tx.maxFeePerGas as string | number) : undefined,\n maxPriorityFeePerGas: tx.maxPriorityFeePerGas !== undefined ? BigInt(tx.maxPriorityFeePerGas as string | number) : undefined,\n } as TransactionSerializable;\n}\n","import {\n mainnet,\n base,\n optimism,\n type Chain,\n} from \"viem/chains\";\nimport { http, type Transport } from \"viem\";\n\ninterface ChainEntry {\n chain: Chain;\n name: string;\n defaultRpcUrl: string;\n}\n\nconst CHAIN_REGISTRY: Record<string, ChainEntry> = {\n \"eip155:1\": { chain: mainnet, name: \"Ethereum\", defaultRpcUrl: \"https://eth.drpc.org\" },\n \"eip155:8453\": { chain: base, name: \"Base\", defaultRpcUrl: \"https://mainnet.base.org\" },\n \"eip155:10\": {\n chain: optimism,\n name: \"Optimism\",\n defaultRpcUrl: \"https://mainnet.optimism.io\",\n },\n};\n\n/** All supported CAIP-2 chain identifiers */\nexport const SUPPORTED_CHAINS = Object.keys(CHAIN_REGISTRY);\n\n/**\n * Resolve a CAIP-2 chain ID to a viem Chain object.\n * Throws if chain is not supported.\n */\nexport function resolveChain(caip2: string): Chain {\n const entry = CHAIN_REGISTRY[caip2];\n if (!entry) {\n throw new Error(\n `Unsupported chain: ${caip2}. Supported: ${SUPPORTED_CHAINS.join(\", \")}`,\n );\n }\n return entry.chain;\n}\n\n/**\n * Get the RPC transport for a chain.\n * Checks for WALLET_RPC_URL_<chainId> env var override first.\n */\nexport function getTransport(caip2: string): Transport {\n const entry = CHAIN_REGISTRY[caip2];\n if (!entry) {\n throw new Error(`Unsupported chain: ${caip2}`);\n }\n\n const chainId = caip2.split(\":\")[1];\n const envUrl = process.env[`WALLET_RPC_URL_${chainId}`];\n return http(envUrl || entry.defaultRpcUrl);\n}\n\n/**\n * Extract the numeric chain ID from a CAIP-2 identifier.\n */\nexport function parseChainId(caip2: string): number {\n const parts = caip2.split(\":\");\n if (parts.length !== 2 || parts[0] !== \"eip155\") {\n throw new Error(`Invalid CAIP-2 chain ID: ${caip2}`);\n }\n return parseInt(parts[1], 10);\n}\n\n/**\n * Get the human-readable name for a CAIP-2 chain.\n */\nexport function getChainName(caip2: string): string {\n const entry = CHAIN_REGISTRY[caip2];\n if (!entry) {\n throw new Error(`Unsupported chain: ${caip2}`);\n }\n return entry.name;\n}\n","import {\n createWalletClient,\n createPublicClient,\n type Hex,\n} from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { resolveChain, getTransport } from \"./chains.js\";\nimport { normalizeTransaction } from \"./signer.js\";\n\n/**\n * Get the native token balance for an address on a chain.\n */\nexport async function getBalance(address: Hex, caip2Chain: string): Promise<bigint> {\n const chain = resolveChain(caip2Chain);\n const transport = getTransport(caip2Chain);\n const client = createPublicClient({ chain, transport });\n return client.getBalance({ address });\n}\n\n/**\n * Send a transaction: estimate gas, set nonce, sign, and broadcast.\n * Returns the transaction hash.\n */\nexport async function sendTransaction(\n privateKey: Hex,\n transaction: Record<string, unknown>,\n caip2Chain: string,\n): Promise<Hex> {\n const chain = resolveChain(caip2Chain);\n const transport = getTransport(caip2Chain);\n const account = privateKeyToAccount(privateKey);\n\n const publicClient = createPublicClient({ chain, transport });\n const walletClient = createWalletClient({ account, chain, transport });\n\n const normalized = normalizeTransaction(transaction);\n\n const request = {\n to: normalized.to as Hex,\n value: normalized.value,\n data: normalized.data as Hex | undefined,\n nonce: normalized.nonce,\n gas: normalized.gas,\n account,\n chain,\n };\n\n // Estimate gas if not provided\n if (!request.gas) {\n request.gas = await publicClient.estimateGas({\n account: account.address,\n to: request.to,\n value: request.value,\n data: request.data,\n });\n }\n\n const hash = await walletClient.sendTransaction(request);\n return hash;\n}\n","import { encodeFunctionData, type Hex } from \"viem\";\n\nexport interface TokenInfo {\n symbol: string;\n decimals: number;\n address?: Hex; // undefined for native ETH\n}\n\n/** USDC contract addresses per CAIP-2 chain */\nconst USDC_ADDRESSES: Record<string, Hex> = {\n \"eip155:1\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n \"eip155:8453\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n \"eip155:10\": \"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85\",\n};\n\n/** Tokens available on each chain */\nconst TOKEN_REGISTRY: Record<string, string[]> = {\n \"eip155:1\": [\"eth\", \"usdc\"],\n \"eip155:8453\": [\"eth\", \"usdc\"],\n \"eip155:10\": [\"eth\", \"usdc\"],\n};\n\n/**\n * Get the list of supported token symbols for a chain.\n */\nexport function getTokenSymbols(chain: string): string[] {\n return TOKEN_REGISTRY[chain] ?? [\"eth\"];\n}\n\n/**\n * Resolve token info for a symbol on a given chain.\n */\nexport function getToken(symbol: string, chain: string): TokenInfo {\n const s = symbol.toLowerCase();\n\n if (s === \"eth\") {\n return { symbol: \"ETH\", decimals: 18 };\n }\n\n if (s === \"usdc\") {\n const address = USDC_ADDRESSES[chain];\n if (!address) {\n throw new Error(`USDC not supported on chain ${chain}`);\n }\n return { symbol: \"USDC\", decimals: 6, address };\n }\n\n throw new Error(`Unknown token: ${symbol}`);\n}\n\n/**\n * Parse a human-readable amount into its smallest unit (wei / micro-USDC).\n */\nexport function parseTokenAmount(amount: string, decimals: number): bigint {\n const [whole = \"0\", frac = \"\"] = amount.split(\".\");\n const paddedFrac = frac.padEnd(decimals, \"0\").slice(0, decimals);\n return BigInt(whole) * 10n ** BigInt(decimals) + BigInt(paddedFrac);\n}\n\nconst ERC20_TRANSFER_ABI = [\n {\n name: \"transfer\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n] as const;\n\n/**\n * Build a raw ERC-20 transfer call (to, data, value=0x0).\n */\nexport function buildErc20Transfer(\n tokenAddress: Hex,\n to: Hex,\n amount: bigint,\n): { to: Hex; data: Hex; value: Hex } {\n const data = encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: \"transfer\",\n args: [to, amount],\n });\n\n return { to: tokenAddress, data, value: \"0x0\" as Hex };\n}\n","import { createInterface } from \"node:readline/promises\";\nimport { stdin, stdout } from \"node:process\";\nimport { SUPPORTED_CHAINS, getChainName } from \"./chains.js\";\nimport { getTokenSymbols } from \"./tokens.js\";\n\nasync function ask(question: string): Promise<string> {\n const rl = createInterface({ input: stdin, output: stdout });\n try {\n const answer = await rl.question(question);\n return answer.trim();\n } finally {\n rl.close();\n }\n}\n\nfunction printOptions(items: { label: string; value: string }[]): void {\n for (let i = 0; i < items.length; i++) {\n process.stderr.write(` ${i + 1}. ${items[i].label}\\n`);\n }\n}\n\n/**\n * Prompt user to select a chain. Returns CAIP-2 identifier.\n */\nexport async function selectChain(): Promise<string> {\n const options = SUPPORTED_CHAINS.map((caip2) => ({\n label: getChainName(caip2),\n value: caip2,\n }));\n\n process.stderr.write(\"\\nSelect chain:\\n\");\n printOptions(options);\n\n const input = await ask(\"> \");\n const idx = parseInt(input, 10) - 1;\n\n if (isNaN(idx) || idx < 0 || idx >= options.length) {\n throw new Error(`Invalid selection: ${input}`);\n }\n\n return options[idx].value;\n}\n\n/**\n * Prompt user to select a token on the given chain. Returns lowercase symbol.\n */\nexport async function selectToken(chain: string): Promise<string> {\n const symbols = getTokenSymbols(chain);\n const options = symbols.map((s) => ({\n label: s.toUpperCase(),\n value: s,\n }));\n\n process.stderr.write(\"\\nSelect token:\\n\");\n printOptions(options);\n\n const input = await ask(\"> \");\n const idx = parseInt(input, 10) - 1;\n\n if (isNaN(idx) || idx < 0 || idx >= options.length) {\n throw new Error(`Invalid selection: ${input}`);\n }\n\n return options[idx].value;\n}\n\n/**\n * Prompt user for a token amount.\n */\nexport async function inputAmount(symbol: string): Promise<string> {\n const input = await ask(`\\nAmount (${symbol.toUpperCase()}): `);\n const num = parseFloat(input);\n\n if (isNaN(num) || num <= 0) {\n throw new Error(`Invalid amount: ${input}`);\n }\n\n return input;\n}\n\n/**\n * Prompt user for an Ethereum address.\n */\nexport async function inputAddress(label: string): Promise<string> {\n const input = await ask(`\\n${label}: `);\n\n if (!/^0x[0-9a-fA-F]{40}$/.test(input)) {\n throw new Error(`Invalid address: ${input}`);\n }\n\n return input;\n}\n","import { parseEther, type Hex } from \"viem\";\nimport { withWallet, resolveProjectId } from \"@walletconnect/cli-sdk\";\nimport { listAddresses } from \"./keystore.js\";\nimport { getToken, parseTokenAmount, buildErc20Transfer } from \"./tokens.js\";\n\nexport interface FundOptions {\n account?: string;\n amount: string;\n chain: string;\n token?: string; // \"eth\" | \"usdc\", defaults to \"eth\"\n}\n\nexport interface FundResult {\n transactionHash: string;\n from: string;\n to: string;\n amount: string;\n token: string;\n}\n\n/**\n * Fund the companion wallet by connecting an external wallet via WalletConnect\n * and sending tokens (native ETH or ERC-20) to the local address.\n */\nexport async function fund(options: FundOptions): Promise<FundResult> {\n const { amount, chain, token: tokenSymbol = \"eth\" } = options;\n\n // Resolve the embedded wallet address\n const embeddedAddress = resolveAccount(options.account);\n const tokenInfo = getToken(tokenSymbol, chain);\n\n // Resolve WalletConnect project ID\n const projectId = resolveProjectId();\n if (!projectId) {\n throw new Error(\n \"WalletConnect project ID not found. Set WALLETCONNECT_PROJECT_ID env var.\",\n );\n }\n\n let result: FundResult | undefined;\n\n await withWallet(\n {\n projectId,\n metadata: {\n name: \"companion-wallet\",\n description: \"Fund companion wallet\",\n url: \"https://walletconnect.com\",\n icons: [],\n },\n chains: [chain],\n methods: [\"eth_sendTransaction\"],\n events: [],\n },\n async (wallet, { accounts }) => {\n // Find an account on the target chain\n const caip10Account = accounts.find((a) => a.startsWith(`${chain}:`));\n if (!caip10Account) {\n throw new Error(\n `No account found on chain ${chain}. Connected accounts: ${accounts.join(\", \")}`,\n );\n }\n\n // Extract the address from CAIP-10 (e.g. \"eip155:1:0xABC...\" → \"0xABC...\")\n const externalAddress = caip10Account.split(\":\").slice(2).join(\":\") as Hex;\n\n let tx: Record<string, Hex>;\n\n if (tokenInfo.address) {\n // ERC-20 transfer (e.g. USDC)\n const rawAmount = parseTokenAmount(amount, tokenInfo.decimals);\n const erc20Tx = buildErc20Transfer(\n tokenInfo.address,\n embeddedAddress as Hex,\n rawAmount,\n );\n tx = { from: externalAddress, ...erc20Tx };\n } else {\n // Native ETH transfer\n const amountWei = parseEther(amount);\n const valueHex = `0x${amountWei.toString(16)}` as Hex;\n tx = {\n from: externalAddress,\n to: embeddedAddress as Hex,\n value: valueHex,\n gas: `0x${(21000).toString(16)}` as Hex,\n };\n }\n\n const transactionHash = await wallet.request<string>({\n chainId: chain,\n request: {\n method: \"eth_sendTransaction\",\n params: [tx],\n },\n });\n\n result = {\n transactionHash,\n from: externalAddress,\n to: embeddedAddress,\n amount,\n token: tokenInfo.symbol,\n };\n },\n );\n\n if (!result) {\n throw new Error(\"Fund operation completed without a result\");\n }\n\n return result;\n}\n\nfunction resolveAccount(account?: string): string {\n if (account) return account;\n\n const addresses = listAddresses();\n if (addresses.length === 0) {\n throw new Error(\"No wallet found. Run 'companion-wallet generate' first.\");\n }\n return addresses[0];\n}\n","import {\n createWalletClient,\n createPublicClient,\n formatEther,\n encodeFunctionData,\n type Hex,\n} from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { loadKey, listAddresses } from \"./keystore.js\";\nimport { resolveChain, getTransport } from \"./chains.js\";\nimport { getToken } from \"./tokens.js\";\n\nexport interface DrainOptions {\n account?: string;\n to: string;\n chain: string;\n token?: string; // \"eth\" | \"usdc\", defaults to \"eth\"\n}\n\nexport interface DrainResult {\n transactionHash: string;\n from: string;\n to: string;\n amount: string;\n token: string;\n}\n\nconst NATIVE_TRANSFER_GAS = 21000n;\n\nconst ERC20_ABI = [\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"transfer\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n] as const;\n\n/**\n * Sweep all tokens from the companion wallet to a destination address.\n * For native ETH: sends balance minus gas cost.\n * For ERC-20 (e.g. USDC): sends full token balance (gas paid in ETH).\n */\nexport async function drain(options: DrainOptions): Promise<DrainResult> {\n const { to, chain, token: tokenSymbol = \"eth\" } = options;\n const tokenInfo = getToken(tokenSymbol, chain);\n\n // Resolve the embedded wallet address\n const account = resolveAccount(options.account);\n\n // Load private key\n const privateKey = loadKey(account);\n const viemAccount = privateKeyToAccount(privateKey);\n\n // Create clients\n const viemChain = resolveChain(chain);\n const transport = getTransport(chain);\n const publicClient = createPublicClient({ chain: viemChain, transport });\n const walletClient = createWalletClient({\n account: viemAccount,\n chain: viemChain,\n transport,\n });\n\n let transactionHash: string;\n let amount: string;\n\n if (tokenInfo.address) {\n // ERC-20 drain: read balance, transfer all\n const balance = await publicClient.readContract({\n address: tokenInfo.address,\n abi: ERC20_ABI,\n functionName: \"balanceOf\",\n args: [viemAccount.address],\n });\n\n if (balance === 0n) {\n throw new Error(`No ${tokenInfo.symbol} balance to drain`);\n }\n\n const data = encodeFunctionData({\n abi: ERC20_ABI,\n functionName: \"transfer\",\n args: [to as Hex, balance],\n });\n\n transactionHash = await walletClient.sendTransaction({\n to: tokenInfo.address,\n data,\n value: 0n,\n });\n\n amount = balance.toString();\n } else {\n // Native ETH drain: send balance minus gas\n const balance = await publicClient.getBalance({ address: viemAccount.address });\n const gasPrice = await publicClient.getGasPrice();\n const gasCost = NATIVE_TRANSFER_GAS * gasPrice;\n const maxSend = balance - gasCost;\n\n if (maxSend <= 0n) {\n throw new Error(\n `Insufficient balance to cover gas. Balance: ${formatEther(balance)} ETH, gas cost: ${formatEther(gasCost)} ETH`,\n );\n }\n\n transactionHash = await walletClient.sendTransaction({\n to: to as Hex,\n value: maxSend,\n gas: NATIVE_TRANSFER_GAS,\n });\n\n amount = maxSend.toString();\n }\n\n return {\n transactionHash,\n from: viemAccount.address,\n to,\n amount,\n token: tokenInfo.symbol,\n };\n}\n\nfunction resolveAccount(account?: string): string {\n if (account) return account;\n\n const addresses = listAddresses();\n if (addresses.length === 0) {\n throw new Error(\"No wallet found. Run 'companion-wallet generate' first.\");\n }\n return addresses[0];\n}\n","import { randomBytes } from \"node:crypto\";\nimport {\n mkdirSync,\n writeFileSync,\n readFileSync,\n renameSync,\n} from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type {\n SessionState,\n SessionPolicy,\n GrantSessionInput,\n SendTransactionInput,\n} from \"./types.js\";\n\nconst SESSIONS_DIR = join(homedir(), \".config\", \"wallet\", \"sessions\");\n\nfunction sessionFilePath(sessionId: string): string {\n return join(SESSIONS_DIR, `${sessionId}.json`);\n}\n\nfunction atomicWrite(filePath: string, content: string): void {\n const tmpPath = filePath + \".tmp\";\n mkdirSync(dirname(filePath), { recursive: true, mode: 0o700 });\n writeFileSync(tmpPath, content, { mode: 0o600 });\n renameSync(tmpPath, filePath);\n}\n\n/**\n * Create a new session.\n */\nexport function grantSession(input: GrantSessionInput): SessionState {\n const sessionId = randomBytes(16).toString(\"hex\");\n\n const session: SessionState = {\n sessionId,\n account: input.account,\n chain: input.chain,\n permissions: input.permissions,\n expiry: input.expiry,\n revoked: false,\n callCounts: {},\n totalValue: {},\n };\n\n atomicWrite(sessionFilePath(sessionId), JSON.stringify(session, null, 2));\n return session;\n}\n\n/**\n * Revoke a session by ID.\n */\nexport function revokeSession(sessionId: string): void {\n const session = loadSession(sessionId);\n session.revoked = true;\n atomicWrite(\n sessionFilePath(sessionId),\n JSON.stringify(session, null, 2),\n );\n}\n\n/**\n * Load a session from disk.\n */\nexport function loadSession(sessionId: string): SessionState {\n const filePath = sessionFilePath(sessionId);\n try {\n const raw = readFileSync(filePath, \"utf-8\");\n return JSON.parse(raw) as SessionState;\n } catch {\n throw new Error(`Session not found: ${sessionId}`);\n }\n}\n\n/**\n * Validate a session for a given operation.\n * Throws on any validation failure.\n */\nexport function validateSession(\n sessionId: string,\n operation: string,\n input?: Record<string, unknown>,\n): SessionState {\n const session = loadSession(sessionId);\n\n if (session.revoked) {\n throw new SessionError(\"Session has been revoked\");\n }\n\n if (Date.now() > session.expiry) {\n throw new SessionError(\"Session has expired\");\n }\n\n // Find permission for this operation\n const permission = session.permissions.find(\n (p) => p.operation === operation,\n );\n if (!permission) {\n throw new SessionError(\n `Session does not permit operation: ${operation}`,\n );\n }\n\n // Validate policies\n if (permission.policies) {\n for (const policy of permission.policies) {\n validatePolicy(policy, session, input);\n }\n }\n\n return session;\n}\n\n/**\n * Record a session operation (update call counts and value totals).\n */\nexport function recordSessionUsage(\n sessionId: string,\n operation: string,\n input?: SendTransactionInput,\n): void {\n const session = loadSession(sessionId);\n\n // Increment call count\n const key = operation;\n session.callCounts[key] = (session.callCounts[key] || 0) + 1;\n\n // Track value for send-transaction\n if (input?.transaction?.value) {\n const chain = input.chain || \"unknown\";\n const currentTotal = BigInt(session.totalValue[chain] || \"0\");\n const txValue = BigInt(input.transaction.value as string | number);\n session.totalValue[chain] = (currentTotal + txValue).toString();\n }\n\n atomicWrite(\n sessionFilePath(sessionId),\n JSON.stringify(session, null, 2),\n );\n}\n\nfunction validatePolicy(\n policy: SessionPolicy,\n session: SessionState,\n input?: Record<string, unknown>,\n): void {\n switch (policy.type) {\n case \"value-limit\": {\n if (!input) break;\n const tx = input.transaction as Record<string, unknown> | undefined;\n if (!tx?.value) break;\n\n const chain = (input.chain as string) || \"unknown\";\n const maxValue = BigInt(policy.params.maxValue as string);\n const currentTotal = BigInt(session.totalValue[chain] || \"0\");\n const txValue = BigInt(tx.value as string | number);\n\n if (currentTotal + txValue > maxValue) {\n throw new SessionError(\n `Value limit exceeded: ${(currentTotal + txValue).toString()} > ${maxValue.toString()}`,\n );\n }\n break;\n }\n\n case \"recipient-allowlist\": {\n if (!input) break;\n const tx = input.transaction as Record<string, unknown> | undefined;\n if (!tx?.to) break;\n\n const allowlist = (policy.params.addresses as string[]).map((a) =>\n a.toLowerCase(),\n );\n const to = (tx.to as string).toLowerCase();\n\n if (!allowlist.includes(to)) {\n throw new SessionError(\n `Recipient ${tx.to} not in allowlist`,\n );\n }\n break;\n }\n\n case \"call-limit\": {\n const maxCalls = policy.params.maxCalls as number;\n const operation = policy.params.operation as string;\n const currentCalls = session.callCounts[operation] || 0;\n\n if (currentCalls >= maxCalls) {\n throw new SessionError(\n `Call limit reached for ${operation}: ${currentCalls} >= ${maxCalls}`,\n );\n }\n break;\n }\n }\n}\n\nexport class SessionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SessionError\";\n }\n}\n","/** CWP exit codes per CAIP-397 */\nexport const ExitCode = {\n SUCCESS: 0,\n ERROR: 1,\n UNSUPPORTED: 2,\n REJECTED: 3,\n TIMEOUT: 4,\n NOT_CONNECTED: 5,\n SESSION_ERROR: 6,\n} as const;\n\nexport type ExitCodeValue = (typeof ExitCode)[keyof typeof ExitCode];\n\n/** CWP operations */\nexport type Operation =\n | \"info\"\n | \"generate\"\n | \"accounts\"\n | \"sign-message\"\n | \"sign-typed-data\"\n | \"sign-transaction\"\n | \"send-transaction\"\n | \"grant-session\"\n | \"revoke-session\"\n | \"get-session\"\n | \"fund\"\n | \"drain\";\n\n/** Info response */\nexport interface InfoResponse {\n name: string;\n version: string;\n rdns: string;\n capabilities: string[];\n chains: string[];\n}\n\n/** Account entry */\nexport interface AccountEntry {\n chain: string;\n address: string;\n}\n\n/** Accounts response */\nexport interface AccountsResponse {\n accounts: AccountEntry[];\n}\n\n/** Sign message input */\nexport interface SignMessageInput {\n account: string;\n message: string;\n sessionId?: string;\n}\n\n/** Sign typed data input */\nexport interface SignTypedDataInput {\n account: string;\n typedData: {\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n primaryType: string;\n message: Record<string, unknown>;\n };\n sessionId?: string;\n}\n\n/** Sign transaction input */\nexport interface SignTransactionInput {\n account: string;\n transaction: Record<string, unknown>;\n chain: string;\n sessionId?: string;\n}\n\n/** Send transaction input */\nexport interface SendTransactionInput {\n account: string;\n transaction: Record<string, unknown>;\n chain: string;\n sessionId?: string;\n}\n\n/** Signature response */\nexport interface SignatureResponse {\n signature: string;\n}\n\n/** Signed transaction response */\nexport interface SignedTransactionResponse {\n signedTransaction: string;\n}\n\n/** Transaction hash response */\nexport interface TransactionHashResponse {\n transactionHash: string;\n}\n\n/** Session permission */\nexport interface SessionPermission {\n operation: string;\n policies?: SessionPolicy[];\n}\n\n/** Session policy */\nexport interface SessionPolicy {\n type: \"value-limit\" | \"recipient-allowlist\" | \"call-limit\";\n params: Record<string, unknown>;\n}\n\n/** Grant session input */\nexport interface GrantSessionInput {\n account: string;\n chain: string;\n permissions: SessionPermission[];\n expiry: number;\n}\n\n/** Grant session response */\nexport interface GrantSessionResponse {\n sessionId: string;\n permissions: SessionPermission[];\n expiry: number;\n}\n\n/** Revoke session input */\nexport interface RevokeSessionInput {\n sessionId: string;\n}\n\n/** Revoke session response */\nexport interface RevokeSessionResponse {\n revoked: true;\n}\n\n/** Get session input */\nexport interface GetSessionInput {\n sessionId: string;\n}\n\n/** Stored session state */\nexport interface SessionState {\n sessionId: string;\n account: string;\n chain: string;\n permissions: SessionPermission[];\n expiry: number;\n revoked: boolean;\n callCounts: Record<string, number>;\n totalValue: Record<string, string>;\n}\n\n/** CWP error response written to stdout on failure */\nexport interface ErrorResponse {\n error: string;\n code: string;\n}\n\n/** Wallet file stored on disk (mnemonic-based) */\nexport interface WalletFile {\n version: 2;\n address: string;\n mnemonic: string;\n}\n"],"mappings":"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","names":["index_exports","__export","ExitCode","SUPPORTED_CHAINS","SessionError","buildErc20Transfer","drain","fund","generateAndStore","getBalance","getChainName","getToken","getTokenSymbols","getTransport","grantSession","inputAddress","inputAmount","keyFilePath","listAddresses","loadKey","loadMnemonic","loadSession","normalizeTransaction","parseChainId","parseTokenAmount","recordSessionUsage","resolveChain","revokeSession","selectChain","selectToken","sendTransaction","signMessage","signTransaction","signTypedData","validateSession","__toCommonJS","import_node_fs","import_node_path","import_node_os","import_accounts","import_viem","KEYS_DIR","keyFilePath","address","generateAndStore","mnemonic","account","filePath","atomicWrite","loadKey","raw","data","loadMnemonic","listAddresses","f","content","tmpPath","import_accounts","import_chains","import_viem","CHAIN_REGISTRY","SUPPORTED_CHAINS","resolveChain","caip2","entry","getTransport","chainId","envUrl","parseChainId","parts","getChainName","signMessage","privateKey","message","signTypedData","typedData","signTransaction","transaction","caip2Chain","account","chainId","parseChainId","tx","normalizeTransaction","import_viem","import_accounts","getBalance","address","caip2Chain","chain","resolveChain","transport","getTransport","sendTransaction","privateKey","transaction","account","publicClient","walletClient","normalized","normalizeTransaction","request","import_viem","USDC_ADDRESSES","TOKEN_REGISTRY","getTokenSymbols","chain","getToken","symbol","s","address","parseTokenAmount","amount","decimals","whole","frac","paddedFrac","ERC20_TRANSFER_ABI","buildErc20Transfer","tokenAddress","to","data","import_promises","import_node_process","ask","question","rl","printOptions","items","i","selectChain","options","SUPPORTED_CHAINS","caip2","getChainName","input","idx","selectToken","chain","getTokenSymbols","s","inputAmount","symbol","num","inputAddress","label","import_viem","import_cli_sdk","fund","options","amount","chain","tokenSymbol","embeddedAddress","resolveAccount","tokenInfo","getToken","projectId","result","wallet","accounts","caip10Account","a","externalAddress","tx","rawAmount","parseTokenAmount","erc20Tx","buildErc20Transfer","valueHex","account","addresses","listAddresses","import_viem","import_accounts","NATIVE_TRANSFER_GAS","ERC20_ABI","drain","options","to","chain","tokenSymbol","tokenInfo","getToken","account","resolveAccount","privateKey","loadKey","viemAccount","viemChain","resolveChain","transport","getTransport","publicClient","walletClient","transactionHash","amount","balance","data","gasPrice","gasCost","maxSend","addresses","listAddresses","import_node_crypto","import_node_fs","import_node_path","import_node_os","SESSIONS_DIR","sessionFilePath","sessionId","atomicWrite","filePath","content","tmpPath","grantSession","input","session","revokeSession","loadSession","raw","validateSession","operation","SessionError","permission","p","policy","validatePolicy","recordSessionUsage","key","chain","currentTotal","txValue","tx","maxValue","allowlist","a","to","maxCalls","currentCalls","message","ExitCode"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/keystore.ts","../src/signer.ts","../src/chains.ts","../src/rpc.ts","../src/tokens.ts","../src/prompt.ts","../src/fund.ts","../src/drain.ts","../src/sessions.ts","../src/types.ts"],"sourcesContent":["export { generateAndStore, loadKey, loadMnemonic, listAddresses, keyFilePath } from \"./keystore.js\";\nexport { signMessage, signTypedData, signTransaction, normalizeTransaction } from \"./signer.js\";\nexport { sendTransaction, getBalance, getTokenBalance, getBalances } from \"./rpc.js\";\nexport { resolveChain, getTransport, parseChainId, getChainName, SUPPORTED_CHAINS } from \"./chains.js\";\nexport { getToken, getTokenSymbols, parseTokenAmount, buildErc20Transfer } from \"./tokens.js\";\nexport type { TokenInfo } from \"./tokens.js\";\nexport { selectChain, selectToken, inputAmount, inputAddress } from \"./prompt.js\";\nexport { fund } from \"./fund.js\";\nexport type { FundOptions, FundResult } from \"./fund.js\";\nexport { drain } from \"./drain.js\";\nexport type { DrainOptions, DrainResult } from \"./drain.js\";\nexport {\n grantSession,\n revokeSession,\n loadSession,\n validateSession,\n recordSessionUsage,\n SessionError,\n} from \"./sessions.js\";\nexport { ExitCode } from \"./types.js\";\nexport type {\n Operation,\n InfoResponse,\n AccountsResponse,\n AccountEntry,\n SignMessageInput,\n SignTypedDataInput,\n SignTransactionInput,\n SendTransactionInput,\n SignatureResponse,\n SignedTransactionResponse,\n TransactionHashResponse,\n GrantSessionInput,\n GrantSessionResponse,\n RevokeSessionInput,\n RevokeSessionResponse,\n GetSessionInput,\n SessionState,\n SessionPermission,\n SessionPolicy,\n BalanceInput,\n BalanceEntry,\n BalanceResponse,\n WalletFile,\n ErrorResponse,\n} from \"./types.js\";\n","import { mkdirSync, writeFileSync, readFileSync, readdirSync, renameSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { generateMnemonic, mnemonicToAccount, english } from \"viem/accounts\";\nimport { getAddress, type Hex } from \"viem\";\nimport type { WalletFile } from \"./types.js\";\n\nconst KEYS_DIR = join(homedir(), \".config\", \"wallet\", \"keys\");\n\n/**\n * Get the path to a key file by address.\n */\nexport function keyFilePath(address: string): string {\n return join(KEYS_DIR, `${getAddress(address)}.json`);\n}\n\n/**\n * Generate a new wallet (BIP-39 mnemonic) and save it to disk.\n * Returns the checksummed address and the mnemonic for backup.\n */\nexport function generateAndStore(): { address: string; mnemonic: string } {\n const mnemonic = generateMnemonic(english);\n const account = mnemonicToAccount(mnemonic);\n const address = getAddress(account.address);\n const filePath = keyFilePath(address);\n\n mkdirSync(dirname(filePath), { recursive: true, mode: 0o700 });\n\n const walletFile: WalletFile = {\n version: 2,\n address,\n mnemonic,\n };\n atomicWrite(filePath, JSON.stringify(walletFile, null, 2));\n\n return { address, mnemonic };\n}\n\n/**\n * Load a private key from disk by deriving it from the stored mnemonic.\n */\nexport function loadKey(address: string): Hex {\n const filePath = keyFilePath(getAddress(address));\n const raw = readFileSync(filePath, \"utf-8\");\n const data = JSON.parse(raw) as WalletFile;\n\n const account = mnemonicToAccount(data.mnemonic);\n return account.getHdKey().privateKey\n ? (`0x${Buffer.from(account.getHdKey().privateKey!).toString(\"hex\")}` as Hex)\n : (() => { throw new Error(\"Failed to derive private key from mnemonic\"); })();\n}\n\n/**\n * Load the mnemonic for an address.\n */\nexport function loadMnemonic(address: string): string {\n const filePath = keyFilePath(getAddress(address));\n const raw = readFileSync(filePath, \"utf-8\");\n const data = JSON.parse(raw) as WalletFile;\n return data.mnemonic;\n}\n\n/**\n * List all stored addresses.\n */\nexport function listAddresses(): string[] {\n try {\n const files = readdirSync(KEYS_DIR);\n return files\n .filter((f) => f.endsWith(\".json\"))\n .map((f) => f.replace(\".json\", \"\"));\n } catch {\n return [];\n }\n}\n\n/**\n * Atomic write: write to .tmp file then rename.\n */\nfunction atomicWrite(filePath: string, content: string): void {\n const tmpPath = filePath + \".tmp\";\n writeFileSync(tmpPath, content, { mode: 0o600 });\n renameSync(tmpPath, filePath);\n}\n","import { privateKeyToAccount } from \"viem/accounts\";\nimport type { Hex, TransactionSerializable } from \"viem\";\nimport { parseChainId } from \"./chains.js\";\n\n/**\n * Sign a plaintext message.\n */\nexport async function signMessage(\n privateKey: Hex,\n message: string,\n): Promise<Hex> {\n const account = privateKeyToAccount(privateKey);\n return account.signMessage({ message });\n}\n\n/**\n * Sign EIP-712 typed data.\n */\nexport async function signTypedData(\n privateKey: Hex,\n typedData: {\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n primaryType: string;\n message: Record<string, unknown>;\n },\n): Promise<Hex> {\n const account = privateKeyToAccount(privateKey);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return account.signTypedData(typedData as any);\n}\n\n/**\n * Sign a transaction (does not broadcast).\n */\nexport async function signTransaction(\n privateKey: Hex,\n transaction: Record<string, unknown>,\n caip2Chain: string,\n): Promise<Hex> {\n const account = privateKeyToAccount(privateKey);\n const chainId = parseChainId(caip2Chain);\n\n const normalized = normalizeTransaction(transaction);\n const tx: TransactionSerializable = {\n ...normalized,\n chainId,\n };\n\n // Default to EIP-1559 if no type or gas pricing fields are provided\n if (!transaction.type && !transaction.gasPrice && !transaction.maxFeePerGas && !transaction.accessList && !transaction.blobs && !transaction.authorizationList) {\n (tx as Record<string, unknown>).type = \"eip1559\";\n }\n\n return account.signTransaction(tx);\n}\n\n/**\n * Normalize transaction fields from JSON input to viem types.\n */\nexport function normalizeTransaction(\n tx: Record<string, unknown>,\n): TransactionSerializable {\n return {\n to: tx.to as Hex | undefined,\n value: tx.value !== undefined ? BigInt(tx.value as string | number) : undefined,\n data: tx.data as Hex | undefined,\n nonce: tx.nonce !== undefined ? Number(tx.nonce) : undefined,\n gas: tx.gas !== undefined ? BigInt(tx.gas as string | number) : undefined,\n gasPrice: tx.gasPrice !== undefined ? BigInt(tx.gasPrice as string | number) : undefined,\n maxFeePerGas: tx.maxFeePerGas !== undefined ? BigInt(tx.maxFeePerGas as string | number) : undefined,\n maxPriorityFeePerGas: tx.maxPriorityFeePerGas !== undefined ? BigInt(tx.maxPriorityFeePerGas as string | number) : undefined,\n } as TransactionSerializable;\n}\n","import {\n mainnet,\n base,\n optimism,\n type Chain,\n} from \"viem/chains\";\nimport { http, type Transport } from \"viem\";\n\ninterface ChainEntry {\n chain: Chain;\n name: string;\n defaultRpcUrl: string;\n}\n\nconst CHAIN_REGISTRY: Record<string, ChainEntry> = {\n \"eip155:1\": { chain: mainnet, name: \"Ethereum\", defaultRpcUrl: \"https://eth.drpc.org\" },\n \"eip155:8453\": { chain: base, name: \"Base\", defaultRpcUrl: \"https://mainnet.base.org\" },\n \"eip155:10\": {\n chain: optimism,\n name: \"Optimism\",\n defaultRpcUrl: \"https://mainnet.optimism.io\",\n },\n};\n\n/** All supported CAIP-2 chain identifiers */\nexport const SUPPORTED_CHAINS = Object.keys(CHAIN_REGISTRY);\n\n/**\n * Resolve a CAIP-2 chain ID to a viem Chain object.\n * Throws if chain is not supported.\n */\nexport function resolveChain(caip2: string): Chain {\n const entry = CHAIN_REGISTRY[caip2];\n if (!entry) {\n throw new Error(\n `Unsupported chain: ${caip2}. Supported: ${SUPPORTED_CHAINS.join(\", \")}`,\n );\n }\n return entry.chain;\n}\n\n/**\n * Get the RPC transport for a chain.\n * Checks for WALLET_RPC_URL_<chainId> env var override first.\n */\nexport function getTransport(caip2: string): Transport {\n const entry = CHAIN_REGISTRY[caip2];\n if (!entry) {\n throw new Error(`Unsupported chain: ${caip2}`);\n }\n\n const chainId = caip2.split(\":\")[1];\n const envUrl = process.env[`WALLET_RPC_URL_${chainId}`];\n return http(envUrl || entry.defaultRpcUrl);\n}\n\n/**\n * Extract the numeric chain ID from a CAIP-2 identifier.\n */\nexport function parseChainId(caip2: string): number {\n const parts = caip2.split(\":\");\n if (parts.length !== 2 || parts[0] !== \"eip155\") {\n throw new Error(`Invalid CAIP-2 chain ID: ${caip2}`);\n }\n return parseInt(parts[1], 10);\n}\n\n/**\n * Get the human-readable name for a CAIP-2 chain.\n */\nexport function getChainName(caip2: string): string {\n const entry = CHAIN_REGISTRY[caip2];\n if (!entry) {\n throw new Error(`Unsupported chain: ${caip2}`);\n }\n return entry.name;\n}\n","import {\n createWalletClient,\n createPublicClient,\n type Hex,\n formatUnits,\n} from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { resolveChain, getTransport } from \"./chains.js\";\nimport { normalizeTransaction } from \"./signer.js\";\nimport { getTokenSymbols, getToken } from \"./tokens.js\";\nimport type { BalanceEntry } from \"./types.js\";\n\n/**\n * Get the native token balance for an address on a chain.\n */\nexport async function getBalance(address: Hex, caip2Chain: string): Promise<bigint> {\n const chain = resolveChain(caip2Chain);\n const transport = getTransport(caip2Chain);\n const client = createPublicClient({ chain, transport });\n return client.getBalance({ address });\n}\n\nconst ERC20_BALANCE_OF_ABI = [\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n] as const;\n\n/**\n * Get the ERC-20 token balance for an address on a chain.\n */\nexport async function getTokenBalance(\n address: Hex,\n tokenAddress: Hex,\n caip2Chain: string,\n): Promise<bigint> {\n const chain = resolveChain(caip2Chain);\n const transport = getTransport(caip2Chain);\n const client = createPublicClient({ chain, transport });\n return client.readContract({\n address: tokenAddress,\n abi: ERC20_BALANCE_OF_ABI,\n functionName: \"balanceOf\",\n args: [address],\n });\n}\n\n/**\n * Get all token balances (native ETH + registered ERC-20s) for an address on a chain.\n */\nexport async function getBalances(\n address: Hex,\n caip2Chain: string,\n): Promise<BalanceEntry[]> {\n const symbols = getTokenSymbols(caip2Chain);\n\n const entries = await Promise.all(\n symbols.map(async (sym) => {\n const token = getToken(sym, caip2Chain);\n let raw: bigint;\n\n if (token.address) {\n raw = await getTokenBalance(address, token.address, caip2Chain);\n } else {\n raw = await getBalance(address, caip2Chain);\n }\n\n return {\n token: token.symbol,\n balance: formatUnits(raw, token.decimals),\n raw: raw.toString(),\n };\n }),\n );\n\n return entries;\n}\n\n/**\n * Send a transaction: estimate gas, set nonce, sign, and broadcast.\n * Returns the transaction hash.\n */\nexport async function sendTransaction(\n privateKey: Hex,\n transaction: Record<string, unknown>,\n caip2Chain: string,\n): Promise<Hex> {\n const chain = resolveChain(caip2Chain);\n const transport = getTransport(caip2Chain);\n const account = privateKeyToAccount(privateKey);\n\n const publicClient = createPublicClient({ chain, transport });\n const walletClient = createWalletClient({ account, chain, transport });\n\n const normalized = normalizeTransaction(transaction);\n\n const request = {\n to: normalized.to as Hex,\n value: normalized.value,\n data: normalized.data as Hex | undefined,\n nonce: normalized.nonce,\n gas: normalized.gas,\n account,\n chain,\n };\n\n // Estimate gas if not provided\n if (!request.gas) {\n request.gas = await publicClient.estimateGas({\n account: account.address,\n to: request.to,\n value: request.value,\n data: request.data,\n });\n }\n\n const hash = await walletClient.sendTransaction(request);\n return hash;\n}\n","import { encodeFunctionData, type Hex } from \"viem\";\n\nexport interface TokenInfo {\n symbol: string;\n decimals: number;\n address?: Hex; // undefined for native ETH\n}\n\n/** USDC contract addresses per CAIP-2 chain */\nconst USDC_ADDRESSES: Record<string, Hex> = {\n \"eip155:1\": \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n \"eip155:8453\": \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n \"eip155:10\": \"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85\",\n};\n\n/** WCT contract addresses per CAIP-2 chain */\nconst WCT_ADDRESSES: Record<string, Hex> = {\n \"eip155:10\": \"0xeF4461891DfB3AC8572cCf7C794664A8DD927945\",\n};\n\n/** Tokens available on each chain */\nconst TOKEN_REGISTRY: Record<string, string[]> = {\n \"eip155:1\": [\"eth\", \"usdc\"],\n \"eip155:8453\": [\"eth\", \"usdc\"],\n \"eip155:10\": [\"eth\", \"usdc\", \"wct\"],\n};\n\n/**\n * Get the list of supported token symbols for a chain.\n */\nexport function getTokenSymbols(chain: string): string[] {\n return TOKEN_REGISTRY[chain] ?? [\"eth\"];\n}\n\n/**\n * Resolve token info for a symbol on a given chain.\n */\nexport function getToken(symbol: string, chain: string): TokenInfo {\n const s = symbol.toLowerCase();\n\n if (s === \"eth\") {\n return { symbol: \"ETH\", decimals: 18 };\n }\n\n if (s === \"usdc\") {\n const address = USDC_ADDRESSES[chain];\n if (!address) {\n throw new Error(`USDC not supported on chain ${chain}`);\n }\n return { symbol: \"USDC\", decimals: 6, address };\n }\n\n if (s === \"wct\") {\n const address = WCT_ADDRESSES[chain];\n if (!address) {\n throw new Error(`WCT not supported on chain ${chain}`);\n }\n return { symbol: \"WCT\", decimals: 18, address };\n }\n\n throw new Error(`Unknown token: ${symbol}`);\n}\n\n/**\n * Parse a human-readable amount into its smallest unit (wei / micro-USDC).\n */\nexport function parseTokenAmount(amount: string, decimals: number): bigint {\n const [whole = \"0\", frac = \"\"] = amount.split(\".\");\n const paddedFrac = frac.padEnd(decimals, \"0\").slice(0, decimals);\n return BigInt(whole) * 10n ** BigInt(decimals) + BigInt(paddedFrac);\n}\n\nconst ERC20_TRANSFER_ABI = [\n {\n name: \"transfer\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n] as const;\n\n/**\n * Build a raw ERC-20 transfer call (to, data, value=0x0).\n */\nexport function buildErc20Transfer(\n tokenAddress: Hex,\n to: Hex,\n amount: bigint,\n): { to: Hex; data: Hex; value: Hex } {\n const data = encodeFunctionData({\n abi: ERC20_TRANSFER_ABI,\n functionName: \"transfer\",\n args: [to, amount],\n });\n\n return { to: tokenAddress, data, value: \"0x0\" as Hex };\n}\n","import { createInterface } from \"node:readline/promises\";\nimport { stdin, stdout } from \"node:process\";\nimport { SUPPORTED_CHAINS, getChainName } from \"./chains.js\";\nimport { getTokenSymbols } from \"./tokens.js\";\n\nasync function ask(question: string): Promise<string> {\n const rl = createInterface({ input: stdin, output: stdout });\n try {\n const answer = await rl.question(question);\n return answer.trim();\n } finally {\n rl.close();\n }\n}\n\nfunction printOptions(items: { label: string; value: string }[]): void {\n for (let i = 0; i < items.length; i++) {\n process.stderr.write(` ${i + 1}. ${items[i].label}\\n`);\n }\n}\n\n/**\n * Prompt user to select a chain. Returns CAIP-2 identifier.\n */\nexport async function selectChain(): Promise<string> {\n const options = SUPPORTED_CHAINS.map((caip2) => ({\n label: getChainName(caip2),\n value: caip2,\n }));\n\n process.stderr.write(\"\\nSelect chain:\\n\");\n printOptions(options);\n\n const input = await ask(\"> \");\n const idx = parseInt(input, 10) - 1;\n\n if (isNaN(idx) || idx < 0 || idx >= options.length) {\n throw new Error(`Invalid selection: ${input}`);\n }\n\n return options[idx].value;\n}\n\n/**\n * Prompt user to select a token on the given chain. Returns lowercase symbol.\n */\nexport async function selectToken(chain: string): Promise<string> {\n const symbols = getTokenSymbols(chain);\n const options = symbols.map((s) => ({\n label: s.toUpperCase(),\n value: s,\n }));\n\n process.stderr.write(\"\\nSelect token:\\n\");\n printOptions(options);\n\n const input = await ask(\"> \");\n const idx = parseInt(input, 10) - 1;\n\n if (isNaN(idx) || idx < 0 || idx >= options.length) {\n throw new Error(`Invalid selection: ${input}`);\n }\n\n return options[idx].value;\n}\n\n/**\n * Prompt user for a token amount.\n */\nexport async function inputAmount(symbol: string): Promise<string> {\n const input = await ask(`\\nAmount (${symbol.toUpperCase()}): `);\n const num = parseFloat(input);\n\n if (isNaN(num) || num <= 0) {\n throw new Error(`Invalid amount: ${input}`);\n }\n\n return input;\n}\n\n/**\n * Prompt user for an Ethereum address.\n */\nexport async function inputAddress(label: string): Promise<string> {\n const input = await ask(`\\n${label}: `);\n\n if (!/^0x[0-9a-fA-F]{40}$/.test(input)) {\n throw new Error(`Invalid address: ${input}`);\n }\n\n return input;\n}\n","import { parseEther, type Hex } from \"viem\";\nimport { withWallet, resolveProjectId } from \"@walletconnect/cli-sdk\";\nimport { listAddresses } from \"./keystore.js\";\nimport { getToken, parseTokenAmount, buildErc20Transfer } from \"./tokens.js\";\n\nexport interface FundOptions {\n account?: string;\n amount: string;\n chain: string;\n token?: string; // \"eth\" | \"usdc\", defaults to \"eth\"\n}\n\nexport interface FundResult {\n transactionHash: string;\n from: string;\n to: string;\n amount: string;\n token: string;\n}\n\n/**\n * Fund the companion wallet by connecting an external wallet via WalletConnect\n * and sending tokens (native ETH or ERC-20) to the local address.\n */\nexport async function fund(options: FundOptions): Promise<FundResult> {\n const { amount, chain, token: tokenSymbol = \"eth\" } = options;\n\n // Resolve the embedded wallet address\n const embeddedAddress = resolveAccount(options.account);\n const tokenInfo = getToken(tokenSymbol, chain);\n\n // Resolve WalletConnect project ID\n const projectId = resolveProjectId();\n if (!projectId) {\n throw new Error(\n \"WalletConnect project ID not found. Set WALLETCONNECT_PROJECT_ID env var.\",\n );\n }\n\n let result: FundResult | undefined;\n\n await withWallet(\n {\n projectId,\n metadata: {\n name: \"companion-wallet\",\n description: \"Fund companion wallet\",\n url: \"https://walletconnect.com\",\n icons: [],\n },\n chains: [chain],\n methods: [\"eth_sendTransaction\"],\n events: [],\n },\n async (wallet, { accounts }) => {\n // Find an account on the target chain\n const caip10Account = accounts.find((a) => a.startsWith(`${chain}:`));\n if (!caip10Account) {\n throw new Error(\n `No account found on chain ${chain}. Connected accounts: ${accounts.join(\", \")}`,\n );\n }\n\n // Extract the address from CAIP-10 (e.g. \"eip155:1:0xABC...\" → \"0xABC...\")\n const externalAddress = caip10Account.split(\":\").slice(2).join(\":\") as Hex;\n\n let tx: Record<string, Hex>;\n\n if (tokenInfo.address) {\n // ERC-20 transfer (e.g. USDC)\n const rawAmount = parseTokenAmount(amount, tokenInfo.decimals);\n const erc20Tx = buildErc20Transfer(\n tokenInfo.address,\n embeddedAddress as Hex,\n rawAmount,\n );\n tx = { from: externalAddress, ...erc20Tx };\n } else {\n // Native ETH transfer\n const amountWei = parseEther(amount);\n const valueHex = `0x${amountWei.toString(16)}` as Hex;\n tx = {\n from: externalAddress,\n to: embeddedAddress as Hex,\n value: valueHex,\n gas: `0x${(21000).toString(16)}` as Hex,\n };\n }\n\n const transactionHash = await wallet.request<string>({\n chainId: chain,\n request: {\n method: \"eth_sendTransaction\",\n params: [tx],\n },\n });\n\n result = {\n transactionHash,\n from: externalAddress,\n to: embeddedAddress,\n amount,\n token: tokenInfo.symbol,\n };\n },\n );\n\n if (!result) {\n throw new Error(\"Fund operation completed without a result\");\n }\n\n return result;\n}\n\nfunction resolveAccount(account?: string): string {\n if (account) return account;\n\n const addresses = listAddresses();\n if (addresses.length === 0) {\n throw new Error(\"No wallet found. Run 'companion-wallet generate' first.\");\n }\n return addresses[0];\n}\n","import {\n createWalletClient,\n createPublicClient,\n formatEther,\n encodeFunctionData,\n type Hex,\n} from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { loadKey, listAddresses } from \"./keystore.js\";\nimport { resolveChain, getTransport } from \"./chains.js\";\nimport { getToken } from \"./tokens.js\";\n\nexport interface DrainOptions {\n account?: string;\n to: string;\n chain: string;\n token?: string; // \"eth\" | \"usdc\", defaults to \"eth\"\n}\n\nexport interface DrainResult {\n transactionHash: string;\n from: string;\n to: string;\n amount: string;\n token: string;\n}\n\nconst NATIVE_TRANSFER_GAS = 21000n;\n\nconst ERC20_ABI = [\n {\n name: \"balanceOf\",\n type: \"function\",\n stateMutability: \"view\",\n inputs: [{ name: \"account\", type: \"address\" }],\n outputs: [{ name: \"\", type: \"uint256\" }],\n },\n {\n name: \"transfer\",\n type: \"function\",\n stateMutability: \"nonpayable\",\n inputs: [\n { name: \"to\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n outputs: [{ name: \"\", type: \"bool\" }],\n },\n] as const;\n\n/**\n * Sweep all tokens from the companion wallet to a destination address.\n * For native ETH: sends balance minus gas cost.\n * For ERC-20 (e.g. USDC): sends full token balance (gas paid in ETH).\n */\nexport async function drain(options: DrainOptions): Promise<DrainResult> {\n const { to, chain, token: tokenSymbol = \"eth\" } = options;\n const tokenInfo = getToken(tokenSymbol, chain);\n\n // Resolve the embedded wallet address\n const account = resolveAccount(options.account);\n\n // Load private key\n const privateKey = loadKey(account);\n const viemAccount = privateKeyToAccount(privateKey);\n\n // Create clients\n const viemChain = resolveChain(chain);\n const transport = getTransport(chain);\n const publicClient = createPublicClient({ chain: viemChain, transport });\n const walletClient = createWalletClient({\n account: viemAccount,\n chain: viemChain,\n transport,\n });\n\n let transactionHash: string;\n let amount: string;\n\n if (tokenInfo.address) {\n // ERC-20 drain: read balance, transfer all\n const balance = await publicClient.readContract({\n address: tokenInfo.address,\n abi: ERC20_ABI,\n functionName: \"balanceOf\",\n args: [viemAccount.address],\n });\n\n if (balance === 0n) {\n throw new Error(`No ${tokenInfo.symbol} balance to drain`);\n }\n\n const data = encodeFunctionData({\n abi: ERC20_ABI,\n functionName: \"transfer\",\n args: [to as Hex, balance],\n });\n\n transactionHash = await walletClient.sendTransaction({\n to: tokenInfo.address,\n data,\n value: 0n,\n });\n\n amount = balance.toString();\n } else {\n // Native ETH drain: send balance minus gas\n const balance = await publicClient.getBalance({ address: viemAccount.address });\n const gasPrice = await publicClient.getGasPrice();\n const gasCost = NATIVE_TRANSFER_GAS * gasPrice;\n const maxSend = balance - gasCost;\n\n if (maxSend <= 0n) {\n throw new Error(\n `Insufficient balance to cover gas. Balance: ${formatEther(balance)} ETH, gas cost: ${formatEther(gasCost)} ETH`,\n );\n }\n\n transactionHash = await walletClient.sendTransaction({\n to: to as Hex,\n value: maxSend,\n gas: NATIVE_TRANSFER_GAS,\n });\n\n amount = maxSend.toString();\n }\n\n return {\n transactionHash,\n from: viemAccount.address,\n to,\n amount,\n token: tokenInfo.symbol,\n };\n}\n\nfunction resolveAccount(account?: string): string {\n if (account) return account;\n\n const addresses = listAddresses();\n if (addresses.length === 0) {\n throw new Error(\"No wallet found. Run 'companion-wallet generate' first.\");\n }\n return addresses[0];\n}\n","import { randomBytes } from \"node:crypto\";\nimport {\n mkdirSync,\n writeFileSync,\n readFileSync,\n renameSync,\n} from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type {\n SessionState,\n SessionPolicy,\n GrantSessionInput,\n SendTransactionInput,\n} from \"./types.js\";\n\nconst SESSIONS_DIR = join(homedir(), \".config\", \"wallet\", \"sessions\");\n\nfunction sessionFilePath(sessionId: string): string {\n return join(SESSIONS_DIR, `${sessionId}.json`);\n}\n\nfunction atomicWrite(filePath: string, content: string): void {\n const tmpPath = filePath + \".tmp\";\n mkdirSync(dirname(filePath), { recursive: true, mode: 0o700 });\n writeFileSync(tmpPath, content, { mode: 0o600 });\n renameSync(tmpPath, filePath);\n}\n\n/**\n * Create a new session.\n */\nexport function grantSession(input: GrantSessionInput): SessionState {\n const sessionId = randomBytes(16).toString(\"hex\");\n\n const session: SessionState = {\n sessionId,\n account: input.account,\n chain: input.chain,\n permissions: input.permissions,\n expiry: input.expiry,\n revoked: false,\n callCounts: {},\n totalValue: {},\n };\n\n atomicWrite(sessionFilePath(sessionId), JSON.stringify(session, null, 2));\n return session;\n}\n\n/**\n * Revoke a session by ID.\n */\nexport function revokeSession(sessionId: string): void {\n const session = loadSession(sessionId);\n session.revoked = true;\n atomicWrite(\n sessionFilePath(sessionId),\n JSON.stringify(session, null, 2),\n );\n}\n\n/**\n * Load a session from disk.\n */\nexport function loadSession(sessionId: string): SessionState {\n const filePath = sessionFilePath(sessionId);\n try {\n const raw = readFileSync(filePath, \"utf-8\");\n return JSON.parse(raw) as SessionState;\n } catch {\n throw new Error(`Session not found: ${sessionId}`);\n }\n}\n\n/**\n * Validate a session for a given operation.\n * Throws on any validation failure.\n */\nexport function validateSession(\n sessionId: string,\n operation: string,\n input?: Record<string, unknown>,\n): SessionState {\n const session = loadSession(sessionId);\n\n if (session.revoked) {\n throw new SessionError(\"Session has been revoked\");\n }\n\n if (Date.now() > session.expiry) {\n throw new SessionError(\"Session has expired\");\n }\n\n // Find permission for this operation\n const permission = session.permissions.find(\n (p) => p.operation === operation,\n );\n if (!permission) {\n throw new SessionError(\n `Session does not permit operation: ${operation}`,\n );\n }\n\n // Validate policies\n if (permission.policies) {\n for (const policy of permission.policies) {\n validatePolicy(policy, session, input);\n }\n }\n\n return session;\n}\n\n/**\n * Record a session operation (update call counts and value totals).\n */\nexport function recordSessionUsage(\n sessionId: string,\n operation: string,\n input?: SendTransactionInput,\n): void {\n const session = loadSession(sessionId);\n\n // Increment call count\n const key = operation;\n session.callCounts[key] = (session.callCounts[key] || 0) + 1;\n\n // Track value for send-transaction\n if (input?.transaction?.value) {\n const chain = input.chain || \"unknown\";\n const currentTotal = BigInt(session.totalValue[chain] || \"0\");\n const txValue = BigInt(input.transaction.value as string | number);\n session.totalValue[chain] = (currentTotal + txValue).toString();\n }\n\n atomicWrite(\n sessionFilePath(sessionId),\n JSON.stringify(session, null, 2),\n );\n}\n\nfunction validatePolicy(\n policy: SessionPolicy,\n session: SessionState,\n input?: Record<string, unknown>,\n): void {\n switch (policy.type) {\n case \"value-limit\": {\n if (!input) break;\n const tx = input.transaction as Record<string, unknown> | undefined;\n if (!tx?.value) break;\n\n const chain = (input.chain as string) || \"unknown\";\n const maxValue = BigInt(policy.params.maxValue as string);\n const currentTotal = BigInt(session.totalValue[chain] || \"0\");\n const txValue = BigInt(tx.value as string | number);\n\n if (currentTotal + txValue > maxValue) {\n throw new SessionError(\n `Value limit exceeded: ${(currentTotal + txValue).toString()} > ${maxValue.toString()}`,\n );\n }\n break;\n }\n\n case \"recipient-allowlist\": {\n if (!input) break;\n const tx = input.transaction as Record<string, unknown> | undefined;\n if (!tx?.to) break;\n\n const allowlist = (policy.params.addresses as string[]).map((a) =>\n a.toLowerCase(),\n );\n const to = (tx.to as string).toLowerCase();\n\n if (!allowlist.includes(to)) {\n throw new SessionError(\n `Recipient ${tx.to} not in allowlist`,\n );\n }\n break;\n }\n\n case \"call-limit\": {\n const maxCalls = policy.params.maxCalls as number;\n const operation = policy.params.operation as string;\n const currentCalls = session.callCounts[operation] || 0;\n\n if (currentCalls >= maxCalls) {\n throw new SessionError(\n `Call limit reached for ${operation}: ${currentCalls} >= ${maxCalls}`,\n );\n }\n break;\n }\n }\n}\n\nexport class SessionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SessionError\";\n }\n}\n","/** CWP exit codes per CAIP-397 */\nexport const ExitCode = {\n SUCCESS: 0,\n ERROR: 1,\n UNSUPPORTED: 2,\n REJECTED: 3,\n TIMEOUT: 4,\n NOT_CONNECTED: 5,\n SESSION_ERROR: 6,\n} as const;\n\nexport type ExitCodeValue = (typeof ExitCode)[keyof typeof ExitCode];\n\n/** CWP operations */\nexport type Operation =\n | \"info\"\n | \"generate\"\n | \"accounts\"\n | \"sign-message\"\n | \"sign-typed-data\"\n | \"sign-transaction\"\n | \"send-transaction\"\n | \"grant-session\"\n | \"revoke-session\"\n | \"get-session\"\n | \"balance\"\n | \"fund\"\n | \"drain\";\n\n/** Info response */\nexport interface InfoResponse {\n name: string;\n version: string;\n rdns: string;\n capabilities: string[];\n chains: string[];\n}\n\n/** Account entry */\nexport interface AccountEntry {\n chain: string;\n address: string;\n}\n\n/** Accounts response */\nexport interface AccountsResponse {\n accounts: AccountEntry[];\n}\n\n/** Sign message input */\nexport interface SignMessageInput {\n account: string;\n message: string;\n sessionId?: string;\n}\n\n/** Sign typed data input */\nexport interface SignTypedDataInput {\n account: string;\n typedData: {\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n primaryType: string;\n message: Record<string, unknown>;\n };\n sessionId?: string;\n}\n\n/** Sign transaction input */\nexport interface SignTransactionInput {\n account: string;\n transaction: Record<string, unknown>;\n chain: string;\n sessionId?: string;\n}\n\n/** Send transaction input */\nexport interface SendTransactionInput {\n account: string;\n transaction: Record<string, unknown>;\n chain: string;\n sessionId?: string;\n}\n\n/** Signature response */\nexport interface SignatureResponse {\n signature: string;\n}\n\n/** Signed transaction response */\nexport interface SignedTransactionResponse {\n signedTransaction: string;\n}\n\n/** Transaction hash response */\nexport interface TransactionHashResponse {\n transactionHash: string;\n}\n\n/** Session permission */\nexport interface SessionPermission {\n operation: string;\n policies?: SessionPolicy[];\n}\n\n/** Session policy */\nexport interface SessionPolicy {\n type: \"value-limit\" | \"recipient-allowlist\" | \"call-limit\";\n params: Record<string, unknown>;\n}\n\n/** Grant session input */\nexport interface GrantSessionInput {\n account: string;\n chain: string;\n permissions: SessionPermission[];\n expiry: number;\n}\n\n/** Grant session response */\nexport interface GrantSessionResponse {\n sessionId: string;\n permissions: SessionPermission[];\n expiry: number;\n}\n\n/** Revoke session input */\nexport interface RevokeSessionInput {\n sessionId: string;\n}\n\n/** Revoke session response */\nexport interface RevokeSessionResponse {\n revoked: true;\n}\n\n/** Get session input */\nexport interface GetSessionInput {\n sessionId: string;\n}\n\n/** Stored session state */\nexport interface SessionState {\n sessionId: string;\n account: string;\n chain: string;\n permissions: SessionPermission[];\n expiry: number;\n revoked: boolean;\n callCounts: Record<string, number>;\n totalValue: Record<string, string>;\n}\n\n/** Balance input */\nexport interface BalanceInput {\n account: string;\n chain: string;\n}\n\n/** Individual token balance entry */\nexport interface BalanceEntry {\n token: string;\n balance: string;\n raw: string;\n}\n\n/** Balance response */\nexport interface BalanceResponse {\n balances: BalanceEntry[];\n}\n\n/** CWP error response written to stdout on failure */\nexport interface ErrorResponse {\n error: string;\n code: string;\n}\n\n/** Wallet file stored on disk (mnemonic-based) */\nexport interface WalletFile {\n version: 2;\n address: string;\n mnemonic: string;\n}\n"],"mappings":"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","names":["index_exports","__export","ExitCode","SUPPORTED_CHAINS","SessionError","buildErc20Transfer","drain","fund","generateAndStore","getBalance","getBalances","getChainName","getToken","getTokenBalance","getTokenSymbols","getTransport","grantSession","inputAddress","inputAmount","keyFilePath","listAddresses","loadKey","loadMnemonic","loadSession","normalizeTransaction","parseChainId","parseTokenAmount","recordSessionUsage","resolveChain","revokeSession","selectChain","selectToken","sendTransaction","signMessage","signTransaction","signTypedData","validateSession","__toCommonJS","import_node_fs","import_node_path","import_node_os","import_accounts","import_viem","KEYS_DIR","keyFilePath","address","generateAndStore","mnemonic","account","filePath","atomicWrite","loadKey","raw","data","loadMnemonic","listAddresses","f","content","tmpPath","import_accounts","import_chains","import_viem","CHAIN_REGISTRY","SUPPORTED_CHAINS","resolveChain","caip2","entry","getTransport","chainId","envUrl","parseChainId","parts","getChainName","signMessage","privateKey","message","signTypedData","typedData","signTransaction","transaction","caip2Chain","account","chainId","parseChainId","tx","normalizeTransaction","import_viem","import_accounts","import_viem","USDC_ADDRESSES","WCT_ADDRESSES","TOKEN_REGISTRY","getTokenSymbols","chain","getToken","symbol","s","address","parseTokenAmount","amount","decimals","whole","frac","paddedFrac","ERC20_TRANSFER_ABI","buildErc20Transfer","tokenAddress","to","data","getBalance","address","caip2Chain","chain","resolveChain","transport","getTransport","ERC20_BALANCE_OF_ABI","getTokenBalance","tokenAddress","getBalances","symbols","getTokenSymbols","sym","token","getToken","raw","sendTransaction","privateKey","transaction","account","publicClient","walletClient","normalized","normalizeTransaction","request","import_promises","import_node_process","ask","question","rl","printOptions","items","i","selectChain","options","SUPPORTED_CHAINS","caip2","getChainName","input","idx","selectToken","chain","getTokenSymbols","s","inputAmount","symbol","num","inputAddress","label","import_viem","import_cli_sdk","fund","options","amount","chain","tokenSymbol","embeddedAddress","resolveAccount","tokenInfo","getToken","projectId","result","wallet","accounts","caip10Account","a","externalAddress","tx","rawAmount","parseTokenAmount","erc20Tx","buildErc20Transfer","valueHex","account","addresses","listAddresses","import_viem","import_accounts","NATIVE_TRANSFER_GAS","ERC20_ABI","drain","options","to","chain","tokenSymbol","tokenInfo","getToken","account","resolveAccount","privateKey","loadKey","viemAccount","viemChain","resolveChain","transport","getTransport","publicClient","walletClient","transactionHash","amount","balance","data","gasPrice","gasCost","maxSend","addresses","listAddresses","import_node_crypto","import_node_fs","import_node_path","import_node_os","SESSIONS_DIR","sessionFilePath","sessionId","atomicWrite","filePath","content","tmpPath","grantSession","input","session","revokeSession","loadSession","raw","validateSession","operation","SessionError","permission","p","policy","validatePolicy","recordSessionUsage","key","chain","currentTotal","txValue","tx","maxValue","allowlist","a","to","maxCalls","currentCalls","message","ExitCode"]}