← Back
/** Variant B (Rick, 16 Jun): unblock auto-redeem/approve/wrap for the tester by adding their
 *  deposit-wallet to the eth_signTypedData_v4 verifyingContract allow-list of the
 *  "polycopy-orders-only" policy (xq797…). Path C (DW Batch) becomes signable again.
 *
 *  ⚠️ This RE-OPENS the withdraw vector for that DW (the batch contents can't be enclave-
 *  allowlisted — see docs/PRIVY_POLICY_SPEC.md). Temporary — redo policies properly later.
 *
 *  PATCH /v1/policies/{id} with app-secret auth (policy is app-owned, owner_id=null).
 *    node update-policy.mjs            → DRY, prints intended rules
 *    APPLY=1 node update-policy.mjs    → PATCH + verify
 */
import fs from 'node:fs';

const APPLY = process.env.APPLY === '1';
const POLICY_ID = process.env.POLICY_ID || 'xq797h4uovkjp5k3tybo3sjb';
const DW = (process.env.DW || '0x8b95fb94829ae79fba30708ea2b768b651cfd3cb').toLowerCase();

const env = {};
for (const l of fs.readFileSync(new URL('../.env.privy', import.meta.url), 'utf8').split('\n')) { const t = l.trim(); if (!t || t.startsWith('#')) continue; const i = t.indexOf('='); if (i > 0) env[t.slice(0, i).trim()] = t.slice(i + 1).trim(); }
const headers = { 'content-type': 'application/json', 'privy-app-id': env.PRIVY_APP_ID, authorization: 'Basic ' + Buffer.from(`${env.PRIVY_APP_ID}:${env.PRIVY_APP_SECRET}`).toString('base64') };

const cur = await (await fetch(`https://api.privy.io/v1/policies/${POLICY_ID}`, { headers })).json();
console.log('current rules:', JSON.stringify(cur.rules));

// Find the eth_signTypedData_v4 verifyingContract rule, append DW to its value list.
const rules = (cur.rules || []).map((r) => {
  const conditions = (r.conditions || []).map((c) => {
    if (c.field === 'verifyingContract' && c.operator === 'in') {
      const vals = (c.value || []).map((v) => String(v));
      if (!vals.map((v) => v.toLowerCase()).includes(DW)) vals.push(DW);
      return { field_source: c.field_source, field: c.field, operator: c.operator, value: vals };
    }
    return { field_source: c.field_source, field: c.field, operator: c.operator, value: c.value };
  });
  return { name: r.name, method: r.method, action: r.action, conditions };
});

const body = { name: cur.name, rules };
console.log('\nnew rules:', JSON.stringify(rules, null, 1));
if (!APPLY) { console.log('\nDRY — re-run with APPLY=1 to PATCH.'); process.exit(0); }

const r = await fetch(`https://api.privy.io/v1/policies/${POLICY_ID}`, { method: 'PATCH', headers, body: JSON.stringify(body) });
const d = await r.json().catch(() => ({}));
console.log('\nPATCH status', r.status, JSON.stringify(d).slice(0, 400));
if (!r.ok) process.exit(1);
const ver = await (await fetch(`https://api.privy.io/v1/policies/${POLICY_ID}`, { headers })).json();
console.log('verified rules:', JSON.stringify(ver.rules));