Skip to content

Latest commit

 

History

History
82 lines (63 loc) · 4.4 KB

File metadata and controls

82 lines (63 loc) · 4.4 KB

SentryPay — Deployment & HSP Settlement Runbook

Two payout rails exist. Pick per network:

Rail settleOnchain Token How funds move Use
On-chain native true (default) HSK ProtectionPool.disburse → HSP router Local + testnet demo (MockHSPRouter)
HSP off-chain false USDC Payer wallet USDC.transfer, HSP adapter observes + signs receipt Mainnet (real HSP)

Why two: HSP is zero-custody — no contract holds or routes funds. The payer's own wallet does a plain USDC.transfer; HSP is a verification/attestation layer on top. verifyingContract 0x…0001 is the EIP-712 signature domain, not a payable router. So on the HSP rail the on-chain trigger only authorizes (emits PayoutExecuted); the monitor's relay settles the beneficiary in USDC.


Step 1 — Testnet deploy (native-HSK demo)

cd contracts
npx hardhat run scripts/deploy-testnet.ts --network hashkeyTestnet   # needs testnet HSK in DEPLOYER

Leaves HSP_ROUTER_ADDRESS_TESTNET blank → deploys MockHSPRouter. The script prints a VITE_* + monitor address block and writes deployments.testnet.env. Paste those into root .env.

Verify the source:

npx hardhat run scripts/verify.ts --network hashkeyTestnet

Step 2 — Testnet end-to-end (native)

npm run dev                       # dashboard → "Deposit Premium" for policy 0
cd monitor && npm run dev         # monitor polls, submits verdict, pool pays native HSK

HSP_SETTLEMENT_ENABLED=false here → on-chain native settlement.

Step 3 — Test the real HSP USDC rail (testnet)

  1. Fund the payer wallet (HSP_PAYER_PRIVATE_KEY, defaults to AI_SIGNER) with test USDC from ${HSP_COORDINATOR_URL}/faucet/.
  2. Confirm .env: USDC_ADDRESS = testnet USDC 0x8FE3…53c6, HSP_CHAIN_NAME=hashkey-testnet, PAYOUT_USDC_BASE_UNITS set, valid HSP_API_KEY.
  3. Dry-run one settlement directly:
    cd monitor
    npx tsx src/settleOnce.ts 0xBeneficiaryAddress 0
    This builds + EIP-712-signs a Mandate, POST /payments, does the USDC.transfer, POST /payments/:id/observe, and prints the adapter receipt.
  4. Full loop: set HSP_SETTLEMENT_ENABLED=true and run npm run dev — the relay settles USDC whenever PayoutExecuted fires.

Step 4 — Mainnet deploy (HSP rail)

Set in .env: SETTLE_ONCHAIN=false, USDC_ADDRESS=0x054ed45810DbBAb8B27668922D110669c9D88D0a (USDC.e), HSP_CHAIN_NAME=hashkey, HSP_CONFIRMATIONS=5, VITE_CHAIN_ID=177. HSP_ROUTER_ADDRESS_MAINNET is the real adapter 0x467A…5012 (has code → passes the deploy code-check; never called while settleOnchain=false).

cd contracts
npx hardhat run scripts/deploy-mainnet.ts --network hashkeyMainnet   # needs real HSK for gas
npx hardhat run scripts/verify.ts --network hashkeyMainnet

Deploy sets settleOnchain=false, prints the mainnet VITE_* block, writes deployments.mainnet.env. Paste into .env, then run the monitor with HSP_SETTLEMENT_ENABLED=true and a USDC-funded payer.

Step 5 — Publish dashboard

The dashboard is a TanStack Start SSR app, so it deploys as a serverless function — not a static dist/ upload. Push to main and Vercel builds automatically using the mainnet VITE_* vars. See CLOUD_DEPLOYMENT.md for the exact Vercel + GitHub Actions setup.

npm run build          # local production build check (uses the mainnet VITE_* vars)
git push               # Vercel auto-deploys the SSR handler

Notes

  • Never put 0x…0001 in an HSP_ROUTER_ADDRESS_* field — it's the EIP-712 verifyingContract, not a router. The mainnet deploy script rejects any router address with no contract code.
  • The @hsp/sdk package is a hackathon GitHub repo (github.com/project-hsp/hsp), not on npm; this project hand-rolls the flow in monitor/src/hspMandate.ts + hspRelay.ts against the Coordinator REST API, matching the SDK's client.ts wire format.
  • POST /payments body: { chain, mandate, attestations: [] } where mandate = { body, signerProof, requiredCapabilities: [] }. In body: signer.profileId = keccak256("eip712-eoa.v1"), signer.payload/recipient.payload are ABI-encoded addresses, refs/binding/requiredCapabilitiesHash = zero. signerProof is the raw 65-byte EIP-712 signature over the Mandate digest. Verified against the repo's mandate-hash test vectors.