nodpay 0.2.40 → 0.2.42

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/scripts/propose.mjs +62 -27
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodpay",
3
- "version": "0.2.40",
3
+ "version": "0.2.42",
4
4
  "description": "NodPay CLI — propose on-chain payments from agent-human shared wallets",
5
5
  "type": "module",
6
6
  "bin": {
@@ -85,6 +85,31 @@ const DEFAULT_SAFE = null; // always use --safe flag
85
85
  const opStoreBase = env('OP_STORE_URL', 'https://nodpay.ai/api');
86
86
  const BUNDLER_URL = `${opStoreBase}/bundler/${CHAIN_ID}`;
87
87
 
88
+ // --- CLI argument parsing (must precede remote_wallet branch) ---
89
+ const args = process.argv.slice(2);
90
+ function getArg(name) {
91
+ const idx = args.indexOf(name);
92
+ return idx !== -1 ? args[idx + 1] : undefined;
93
+ }
94
+ function hasFlag(name) {
95
+ return args.includes(name);
96
+ }
97
+
98
+ const to = getArg('--to');
99
+ const valueEth = getArg('--value-eth') || getArg('--value') || '0';
100
+ const safeOverride = getArg('--safe');
101
+ let isCounterfactual = hasFlag('--counterfactual');
102
+ const humanSigner = getArg('--human-signer-eoa');
103
+ const salt = getArg('--salt') || '1001';
104
+
105
+ // Passkey support
106
+ let passkeyX = getArg('--human-signer-passkey-x');
107
+ let passkeyY = getArg('--human-signer-passkey-y');
108
+ const passkeyRawId = getArg('--passkey-raw-id');
109
+ const passkeyVerifier = getArg('--passkey-verifier') || '0x445a0683e494ea0c5AF3E83c5159fBE47Cf9e765';
110
+ let recoverySigner = getArg('--recovery-signer');
111
+ let isPasskey = !!(passkeyX && passkeyY);
112
+
88
113
  // --- Agent key resolution: remote_wallet (config.json) or local key ---
89
114
  const _config = loadConfig();
90
115
  const _remoteWalletUrl = _config.remote_wallet || null;
@@ -113,6 +138,18 @@ if (_remoteWalletUrl) {
113
138
  }
114
139
  AGENT_ADDRESS = wallets[0].agentSigner;
115
140
 
141
+ // remote_wallet: extract passkey/recovery from wallet data for approvalContext
142
+ // (CLI args take precedence if provided, but agents in remote_wallet mode don't pass them)
143
+ const rw = wallets[0];
144
+ if (!passkeyX && rw.humanSignerPasskeyX) {
145
+ passkeyX = rw.humanSignerPasskeyX;
146
+ passkeyY = rw.humanSignerPasskeyY;
147
+ isPasskey = true;
148
+ }
149
+ if (!recoverySigner && rw.recoverySigner) {
150
+ recoverySigner = rw.recoverySigner;
151
+ }
152
+
116
153
  signHash = async (hash) => {
117
154
  const signRes = await fetch(`${_remoteWalletUrl.replace(/\/$/, '')}/sign`, {
118
155
  method: 'POST',
@@ -142,30 +179,6 @@ if (_remoteWalletUrl) {
142
179
  };
143
180
  }
144
181
 
145
- const args = process.argv.slice(2);
146
- function getArg(name) {
147
- const idx = args.indexOf(name);
148
- return idx !== -1 ? args[idx + 1] : undefined;
149
- }
150
- function hasFlag(name) {
151
- return args.includes(name);
152
- }
153
-
154
- const to = getArg('--to');
155
- const valueEth = getArg('--value-eth') || getArg('--value') || '0';
156
- const safeOverride = getArg('--safe');
157
- let isCounterfactual = hasFlag('--counterfactual');
158
- const humanSigner = getArg('--human-signer-eoa');
159
- const salt = getArg('--salt') || '1001';
160
-
161
- // Passkey support
162
- const passkeyX = getArg('--human-signer-passkey-x');
163
- const passkeyY = getArg('--human-signer-passkey-y');
164
- const passkeyRawId = getArg('--passkey-raw-id');
165
- const passkeyVerifier = getArg('--passkey-verifier') || '0x445a0683e494ea0c5AF3E83c5159fBE47Cf9e765';
166
- const recoverySigner = getArg('--recovery-signer');
167
- const isPasskey = !!(passkeyX && passkeyY);
168
-
169
182
  // remote_wallet + --human-signer-eoa is not supported
170
183
  if (_remoteWalletUrl && humanSigner) {
171
184
  console.error(JSON.stringify({ error: 'remote_wallet and --human-signer-eoa cannot be combined. Remote mode only supports passkey wallets.' }));
@@ -582,8 +595,28 @@ try {
582
595
  writeFileSync(join(PENDING_DIR, `4337-${shortId}.json`), JSON.stringify(result, null, 2));
583
596
 
584
597
  // Store to op-store API for hash-based web app lookup
585
- // NOTE: signerType intentionally NOT sent it's determined by user's browser
586
- // (localStorage), not by agent. See ARCHITECTURE.md Client Verification Chain.
598
+ // Build approvalContext: server-side approval context (replaces localStorage dependency)
599
+ const approvalContext = isPasskey
600
+ ? {
601
+ version: 1,
602
+ signerType: 'passkey',
603
+ rpId: walletRpId || 'nodpay.ai',
604
+ passkeyX,
605
+ passkeyY,
606
+ recoveryAddress: recoverySigner || null,
607
+ safeAddress,
608
+ chainId: parseInt(CHAIN_ID, 10),
609
+ }
610
+ : humanSigner
611
+ ? {
612
+ version: 1,
613
+ signerType: 'eoa',
614
+ humanSignerAddress: humanSigner,
615
+ safeAddress,
616
+ chainId: parseInt(CHAIN_ID, 10),
617
+ }
618
+ : null;
619
+
587
620
  const storePayload = {
588
621
  safeOperationJson,
589
622
  userOpHash: entryPointUserOpHash,
@@ -596,10 +629,12 @@ try {
596
629
  agent: AGENT_ADDRESS,
597
630
  agentSignature: safeOperationJson.signatures,
598
631
  createdAt: new Date().toISOString(),
599
- // SafeClaw integration: passkey coordinates + recovery for approve page fallback
632
+ // Legacy fields (kept for URL-param fallback during transition)
600
633
  passkeyX: passkeyX || null,
601
634
  passkeyY: passkeyY || null,
602
635
  recoveryAddress: recoverySigner || null,
636
+ // Server-side approval context
637
+ approvalContext,
603
638
  };
604
639
 
605
640
  // Extract raw agent signature for server auth