# 1AM Wallet — Full Integration Reference for AI Models # URL: https://1am.xyz/ai.txt # Use this document to integrate DApps with the 1AM wallet on Midnight Network. ## Overview 1AM is a self-custodial wallet for the Midnight Network (a privacy-first L1 blockchain). Users never need dust or gas tokens — ProofStation sponsors all transaction fees server-side. ## Detect the Wallet The 1AM wallet injects at window.midnight['1am']: ```typescript function detectWallet(): Promise { return new Promise((resolve) => { const wallet = window.midnight?.['1am']; if (wallet) { resolve(wallet); return; } let attempts = 0; const interval = setInterval(() => { const w = window.midnight?.['1am']; if (w) { clearInterval(interval); resolve(w); } else if (++attempts > 50) { clearInterval(interval); resolve(null); } }, 100); }); } ``` ## Connect ```typescript const wallet = await detectWallet(); if (!wallet) throw new Error('1AM wallet not installed'); const api = await wallet.connect('preview'); // or 'preprod' ``` ## Get Addresses & Balances ```typescript const { shieldedAddress } = await api.getShieldedAddresses(); const { unshieldedAddress } = await api.getUnshieldedAddress(); const { dustAddress } = await api.getDustAddress(); const shieldedBalances = await api.getShieldedBalances(); // Record const unshieldedBalances = await api.getUnshieldedBalances(); // Record const { balance, cap } = await api.getDustBalance(); ``` ## Get Network Configuration ```typescript const config = await api.getConfiguration(); // Returns: { networkId, indexerUri, indexerWsUri, proverServerUri, substrateNodeUri } ``` ## Build Providers (Dust-Free) ```typescript import { setNetworkId } from '@midnight-ntwrk/midnight-js-network-id'; import { FetchZkConfigProvider } from '@midnight-ntwrk/midnight-js-fetch-zk-config-provider'; import { indexerPublicDataProvider } from '@midnight-ntwrk/midnight-js-indexer-public-data-provider'; const config = await api.getConfiguration(); setNetworkId(config.networkId); const zkConfigProvider = new FetchZkConfigProvider( 'https://your-app.com/contract/compiled/your-contract', fetch.bind(window), ); const publicDataProvider = indexerPublicDataProvider(config.indexerUri, config.indexerWsUri); const provingProvider = await api.getProvingProvider(zkConfigProvider); const proofProvider = { async proveTx(unprovenTx) { const { CostModel } = await import('@midnight-ntwrk/ledger-v8'); return unprovenTx.prove(provingProvider, CostModel.initialCostModel()); }, }; const shieldedAddress = await api.getShieldedAddresses(); const walletProvider = { getCoinPublicKey: () => shieldedAddress.shieldedCoinPublicKey, getEncryptionPublicKey: () => shieldedAddress.shieldedEncryptionPublicKey, async balanceTx(tx) { const hex = Array.from(tx.serialize()).map(b => b.toString(16).padStart(2, '0')).join(''); const result = await api.balanceUnsealedTransaction(hex); const { Transaction } = await import('@midnight-ntwrk/ledger-v8'); const bytes = new Uint8Array(result.tx.match(/.{2}/g).map(b => parseInt(b, 16))); return Transaction.deserialize('signature', 'proof', 'binding', bytes); }, }; const midnightProvider = { async submitTx(tx) { const hex = Array.from(tx.serialize()).map(b => b.toString(16).padStart(2, '0')).join(''); await api.submitTransaction(hex); return tx.identifiers()[0]; }, }; ``` ## Deploy a Contract ```typescript import { CompiledContract } from '@midnight-ntwrk/compact-js'; import { deployContract } from '@midnight-ntwrk/midnight-js-contracts'; import { Contract } from './your-compiled-contract'; const compiledContract = CompiledContract.make('YourContract', Contract).pipe( CompiledContract.withVacantWitnesses, CompiledContract.withCompiledFileAssets('./contract/compiled/your-contract'), ); const providers = { publicDataProvider, zkConfigProvider, proofProvider, walletProvider, midnightProvider }; const deployed = await deployContract(providers, { compiledContract }); console.log('Contract address:', deployed.deployTxData.public.contractAddress); ``` ## Call a Circuit ```typescript import { submitCallTx } from '@midnight-ntwrk/midnight-js-contracts'; const result = await submitCallTx(providers, { compiledContract, contractAddress: '09dbe05f...', circuitId: 'register', args: [nameHash, 1n], }); console.log('Tx hash:', result.public.txHash); ``` ## Transaction Flow 1. DApp builds unproven tx (SDK + compiled contract) 2. proofProvider.proveTx() → wallet → ProofStation /check + /prove → ZK proof (~2-5s) 3. walletProvider.balanceTx() → wallet → ProofStation /balance-only → server adds dust fees 4. midnightProvider.submitTx() → wallet → broadcasts to Midnight chain Total user cost: 0 NIGHT, 0 dust. ProofStation sponsors all fees. ## DApp Connector API — InitialAPI (window.midnight['1am']) | Method | Returns | Description | |--------|---------|-------------| | connect(networkId) | ConnectedAPI | Connect to wallet on given network | | name | string | '1AM' | | apiVersion | string | '4.0.0' | ## DApp Connector API — ConnectedAPI | Method | Returns | Description | |--------|---------|-------------| | getShieldedBalances() | Record | Shielded token balances | | getUnshieldedBalances() | Record | Unshielded token balances | | getDustBalance() | { cap, balance } | Dust balance | | getShieldedAddresses() | { shieldedAddress, shieldedCoinPublicKey, shieldedEncryptionPublicKey } | Shielded keys | | getUnshieldedAddress() | { unshieldedAddress } | Unshielded address | | getDustAddress() | { dustAddress } | Dust address | | getConfiguration() | Configuration | Network URLs, proof server | | balanceUnsealedTransaction(txHex) | { tx } | Balance a proved tx (server pays dust) | | submitTransaction(txHex) | void | Submit to chain | | getProvingProvider(keyProvider) | ProvingProvider | Get ZK proving provider | | signData(data, options) | Signature | Sign arbitrary data | | makeTransfer(outputs) | { tx } | Create a token transfer | ## ProofStation API Endpoints | Endpoint | Method | Description | |----------|--------|-------------| | /health | GET | Server health + wallet status | | /prove | POST | Prove a ZK circuit (native binary) | | /check | POST | Check circuit constraints | | /balance-only | POST | Add dust to proved tx, return balanced tx | | /wallet-status | GET | Balance service wallet info | Auth: X-API-Key header required. Contact 1am.xyz for access. ## Live Networks | Network | Proof Server | Indexer | RPC | |---------|-------------|---------|-----| | preview | api-preview.1am.xyz | indexer.preview.midnight.network | rpc.preview.midnight.network | | preprod | api-preprod.1am.xyz | indexer.preprod.midnight.network | rpc.preprod.midnight.network | | mainnet | TBD | TBD | TBD | ## NPM Dependencies @midnight-ntwrk/compact-js @midnight-ntwrk/midnight-js-contracts @midnight-ntwrk/midnight-js-types @midnight-ntwrk/midnight-js-fetch-zk-config-provider @midnight-ntwrk/midnight-js-indexer-public-data-provider @midnight-ntwrk/midnight-js-network-id @midnight-ntwrk/ledger-v8 ## ZK Key Hosting Host compiled contract keys on any CDN with CORS enabled: keys/circuitName.prover (2-10 MB) keys/circuitName.verifier (2 KB) zkir/circuitName.bzkir (1-3 KB) FetchZkConfigProvider fetches: {baseURL}/keys/{circuitId}.prover, .verifier, zkir/{circuitId}.bzkir ## Working Example ZKMint Night-ID: https://zkmint.1am.xyz Full E2E: detect wallet → connect → build providers → deploy contract → call circuit → submit User cost: zero. ProofStation sponsors all fees. ## Claude Code Skill Install the 1AM Midnight Skill to give Claude full integration knowledge: /install-skill https://github.com/webisoftSoftware/1AM-Midnight-Skill The skill covers: wallet detection, provider setup, dust-free execution, contract deployment, ZK key hosting, and app registry listing. ## Links Website: https://1am.xyz Developer Docs: https://1am.xyz/developers AI Integration Reference: https://1am.xyz/ai.txt Install Beta: https://1am.xyz/install-beta Explorer: https://explorer.1am.xyz Proof Station: https://proofstation.1am.xyz Claude Code Skill: https://github.com/webisoftSoftware/1AM-Midnight-Skill Twitter: https://x.com/oneamxyz Midnight SDK: https://docs.midnight.network