B03.1. Prepares a Privy application, execution wallet, policy, and Arc Testnet funding so a real settlement can be captured as Gate P4 evidence.
A human runs every step here. Agents must not create accounts, enter credentials, mutate policy, or move funds. An agent may run the read-only verification in section 7 and report results.
Testnet only. Nothing in this guide applies to mainnet, and Arc mainnet
parameters are unpublished. See docs/settlement/SETTLEMENT_CONFIG_V1.md.
You need a Privy account, a terminal, and somewhere to store secrets that is not this repository. Budget about 30 minutes.
At no point paste a secret into a chat, an issue, a PR, a fixture, a log, or a
review prompt. .agent/SECURITY_INVARIANTS.md treats that as a breach, and a
committed secret must be rotated, not deleted.
- Create a Privy application for OneShot.
- Record the app ID. It is a public identifier, safe to log.
- Create an app secret. This is the one true credential in the system. Put it straight into your secret store; do not write it to a file first.
- Create a server wallet. This is the wallet that signs server-owned settlement paths.
- Record the wallet ID and the wallet address.
- Configure the owner or key quorum according to your organisation's rules. A single-owner wallet is acceptable for a testnet demo and is not acceptable for anything holding real value.
The Team Report browser flow is user-funded and does not use this wallet. The
connected Privy Ethereum wallet signs the reviewed ERC-20 transfer in the
browser; the API verifies its Arc receipt through the credential-free
ONESHOT_ARC_RPC_URL read-only endpoint. This runbook still applies to the
worker-owned Arc integrations.
Two human decisions, both deliberate:
- Recipient allowlist. The addresses settlement may pay. Keep it as short as the demo allows. An empty list settles nothing, which is the safe default.
- Per-settlement cap. The maximum atomic units for one settlement, in
six-decimal USDC atomic units.
1000000is one USDC.
These are the two values that bound the blast radius if everything else fails.
Attach a policy to the execution wallet constraining all six dimensions:
| Dimension | Constraint |
|---|---|
| Chain | equals 5042002 |
| Destination contract | equals the USDC interface 0x3600000000000000000000000000000000000000 |
| Native value | equals 0 |
| Method | transfer |
| Recipient | in your allowlist |
| Amount | at or below your cap |
The policy must end with a default deny. Without it, anything the rules do not mention is permitted.
buildExpectedPolicy in @oneshot/privy-adapter produces this shape, and
policyDigest produces a fingerprint you can compare against later to detect
drift. Record the policy ID and the digest.
- Fund the execution wallet from an Arc Testnet faucet.
- Fund only what the demo needs.
- Confirm the balance on the explorer at https://testnet.arcscan.app.
Arc's native gas asset uses 18 decimals while the USDC ERC-20 interface uses 6. They are both called USDC. Read balances carefully.
Set the variables from packages/arc-adapter/.env.example in your shell or
secret store, then run the readiness probe:
cd packages/arc-adapter && npm run probeThis contacts the endpoint you configured, asks it which chain it is actually
on, checks that the configured USDC address holds contract bytecode, and reads
the token's decimals() value. It is read-only: it cannot sign, send, or
mutate anything, and it prints no credential. Exit code 0 means ready, 1 means
not ready.
Read the result carefully, because the two failure modes need opposite responses:
MISMATCH— the endpoint answered and the answer was wrong. Your configuration points somewhere it should not. A human must fix it. Do not retry; it will not resolve on its own.UNAVAILABLE— the endpoint could not be reached. Your configuration may be perfectly correct. Retrying later is reasonable.
Note that npm run check is a different thing: it runs lint, typecheck, and
the unit tests against stubbed endpoints. It proves the probe's logic is
correct and tells you nothing about whether your setup is correct. Only
npm run probe does that.
| Value | Classification | Where it goes |
|---|---|---|
| App ID | public | configuration |
| App secret | secret | secret store only |
| Wallet ID | public | configuration |
| Wallet address | public | configuration and evidence |
| Policy ID | public | configuration |
| Recipient allowlist | human-only | configuration |
| Cap | human-only | configuration |
Never commit a real value. packages/arc-adapter/.env.example holds
placeholders only and is generated from the config schema.
When the demo is finished:
- Return or drain remaining testnet funds.
- Rotate the app secret, and rotate immediately if it was ever pasted anywhere outside the secret store.
- Narrow or empty the recipient allowlist.
- Keep the wallet and policy if you need the evidence trail; disable the policy's allow rule to make the wallet inert.
Rotation is the response to a suspected leak. Deleting the message that contained it is not.