3:I[4707,[],""]
5:I[6423,[],""]
6:I[6665,["7281","static/chunks/7281-843e037a8e70f2dc.js","2972","static/chunks/2972-206c84f960364fc8.js","5315","static/chunks/5315-f69dee48ed012c1d.js","815","static/chunks/815-3b9d8cc363060263.js","2490","static/chunks/2490-f3452dfcdf496696.js","6529","static/chunks/app/(docs)/layout-4fa0829f760f53cf.js"],"Navbar"]
7:I[6812,["7281","static/chunks/7281-843e037a8e70f2dc.js","2972","static/chunks/2972-206c84f960364fc8.js","5315","static/chunks/5315-f69dee48ed012c1d.js","815","static/chunks/815-3b9d8cc363060263.js","2490","static/chunks/2490-f3452dfcdf496696.js","6529","static/chunks/app/(docs)/layout-4fa0829f760f53cf.js"],"Footer"]
4:["slug","developer-guide","d"]
8:{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"}
9:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"}
a:{"display":"inline-block"}
b:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0}
0:["lhuH3gKfmvR-zf5xG0U6e",[[["",{"children":["(docs)",{"children":["docs",{"children":[["slug","developer-guide","d"],{"children":["__PAGE__?{\"slug\":\"developer-guide\"}",{}]}]}]}]},"$undefined","$undefined",true],["",{"children":["(docs)",{"children":["docs",{"children":[["slug","developer-guide","d"],{"children":["__PAGE__",{},[["$L1","$L2",null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","(docs)","children","docs","children","$4","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","(docs)","children","docs","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[null,["$","main",null,{"className":"min-h-screen relative z-10","children":[["$","$L6",null,{}],["$","div",null,{"className":"pt-24 pb-16 max-w-4xl mx-auto px-6","children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","(docs)","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}],["$","$L7",null,{}]]}]],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/next/static/css/7d3295cdb652feda.css","precedence":"next","crossOrigin":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/next/static/css/c025d3bf1b5d959c.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"en","data-theme":"dark","className":"__variable_aa659e __variable_a607d1 __variable_ba5569 __variable_595324","children":["$","body",null,{"className":"bg-[var(--bg-base)]","children":["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$8","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$9","children":"404"}],["$","div",null,{"style":"$a","children":["$","h2",null,{"style":"$b","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}]}]}]],null],null],["$Lc",null]]]]
d:I[9836,["7281","static/chunks/7281-843e037a8e70f2dc.js","2972","static/chunks/2972-206c84f960364fc8.js","7775","static/chunks/app/(docs)/docs/%5Bslug%5D/page-edcecef592b5c2ea.js"],"DocArticle"]
e:I[2972,["7281","static/chunks/7281-843e037a8e70f2dc.js","2972","static/chunks/2972-206c84f960364fc8.js","7775","static/chunks/app/(docs)/docs/%5Bslug%5D/page-edcecef592b5c2ea.js"],""]
f:T874,import { useState, useEffect, useCallback } from 'react';

interface CantonWallet {
  isCantonWallet: boolean;
  version: string;
  connect: (options?: { dappName?: string }) => Promise<{ partyId: string }>;
  disconnect: () => Promise<void>;
  isConnected: () => Promise<boolean>;
  getPartyId: () => Promise<{ partyId: string }>;
  getBalances: () => Promise<unknown>;
  signAndSubmit: (tx: Record<string, unknown>) => Promise<{ transactionId: string }>;
  on: (event: string, handler: (data?: unknown) => void) => void;
  off: (event: string, handler: (data?: unknown) => void) => void;
}

export function useZoff() {
  const [isConnected, setIsConnected] = useState(false);
  const [partyId, setPartyId] = useState<string | null>(null);

  useEffect(() => {
    const wallet = (window as any).cantonWallet as CantonWallet | undefined;
    if (!wallet) return;

    const onAccountChanged = (newPartyId: unknown) => {
      setPartyId(newPartyId as string);
    };

    const onDisconnect = () => {
      setIsConnected(false);
      setPartyId(null);
    };

    wallet.on('accountChanged', onAccountChanged);
    wallet.on('disconnect', onDisconnect);

    return () => {
      wallet.off('accountChanged', onAccountChanged);
      wallet.off('disconnect', onDisconnect);
    };
  }, []);

  const connect = useCallback(async () => {
    const wallet = (window as any).cantonWallet as CantonWallet | undefined;
    if (!wallet) throw new Error('Zoff Wallet not installed');

    const result = await wallet.connect();
    setIsConnected(true);
    setPartyId(result.partyId);
  }, []);

  const disconnect = useCallback(async () => {
    const wallet = (window as any).cantonWallet as CantonWallet | undefined;
    await wallet?.disconnect();
    setIsConnected(false);
    setPartyId(null);
  }, []);

  const signAndSubmit = useCallback(async (transaction: Record<string, unknown>) => {
    const wallet = (window as any).cantonWallet as CantonWallet | undefined;
    if (!wallet) throw new Error('Zoff Wallet not installed');
    return wallet.signAndSubmit(transaction);
  }, []);

  return { isConnected, partyId, connect, disconnect, signAndSubmit };
}
2:["$","$Ld",null,{"children":[["$","$Le",null,{"href":"/docs","className":"inline-flex items-center gap-1.5 text-sm text-[var(--text-tertiary)] hover:text-[var(--orange)] transition-colors mb-8","children":[["$","svg",null,{"width":"16","height":"16","viewBox":"0 0 24 24","fill":"none","stroke":"currentColor","strokeWidth":"2","strokeLinecap":"round","children":[["$","path",null,{"d":"M19 12H5"}],["$","path",null,{"d":"M12 19l-7-7 7-7"}]]}],"Back to docs"]}],["$","article",null,{"className":"prose-zoff","children":[["$","h1","h1-0",{"children":"Developer Guide"}],"\n",["$","p","p-0",{"children":"Integrate your Canton dApp with Zoff Wallet. Users connect, you submit Daml commands, Zoff handles signing."}],"\n",["$","h2","h2-0",{"children":"Overview"}],"\n",["$","p","p-1",{"children":["Zoff injects a provider at ",["$","code","code-0",{"children":"window.cantonWallet"}]," on every page where the extension is active. The provider exposes direct methods for connecting, querying, and submitting transactions. If you've built for MetaMask on Ethereum, the mental model is similar: detect the provider, request a connection, submit transactions."]}],"\n",["$","h2","h2-1",{"children":"Detecting Zoff Wallet"}],"\n",["$","pre","pre-0",{"children":["$","code","code-0",{"className":"language-javascript","children":"// Check if Zoff is installed\nif (typeof window.cantonWallet !== 'undefined') {\n  console.log('Zoff Wallet detected');\n  console.log('Version:', window.cantonWallet.version);\n} else {\n  console.log('No Canton wallet found');\n}\n"}]}],"\n",["$","p","p-2",{"children":"The provider object exposes two boolean flags for identification:"}],"\n",["$","ul","ul-0",{"children":["\n",["$","li","li-0",{"children":[["$","code","code-0",{"children":"window.cantonWallet.isCantonWallet"}]," — always ",["$","code","code-1",{"children":"true"}]]}],"\n",["$","li","li-1",{"children":[["$","code","code-0",{"children":"window.cantonWallet.isExtension"}]," — always ",["$","code","code-1",{"children":"true"}]]}],"\n"]}],"\n",["$","h2","h2-2",{"children":"Connecting to the Wallet"}],"\n",["$","pre","pre-1",{"children":["$","code","code-0",{"className":"language-javascript","children":"const result = await window.cantonWallet.connect({\n  dappName: 'My Canton dApp',\n});\n\n// result contains the user's active party ID\nconsole.log(result.partyId); // \"party::1a2b3c...\"\n"}]}],"\n",["$","p","p-3",{"children":["When your dApp calls ",["$","code","code-0",{"children":"connect()"}],", Zoff shows the user a connection approval popup displaying your origin. The user can approve or reject. If approved, your origin is stored in the user's connected dApps list and persists across sessions until revoked."]}],"\n",["$","h2","h2-3",{"children":"Provider Methods"}],"\n",["$","h3","h3-0",{"children":["$","code","code-0",{"children":"connect(options?)"}]}],"\n",["$","p","p-4",{"children":"Request wallet connection. Returns the user's active party ID."}],"\n",["$","pre","pre-2",{"children":["$","code","code-0",{"className":"language-javascript","children":"const { partyId } = await window.cantonWallet.connect({\n  dappName: 'My dApp',               // optional\n  requestedPermissions: ['sign'],     // optional\n});\n"}]}],"\n",["$","p","p-5",{"children":["$","strong","strong-0",{"children":"Parameters:"}]}],"\n",["$","table","table-0",{"children":[["$","thead","thead-0",{"children":["$","tr","tr-0",{"children":[["$","th","th-0",{"children":"Field"}],["$","th","th-1",{"children":"Type"}],["$","th","th-2",{"children":"Description"}]]}]}],["$","tbody","tbody-0",{"children":[["$","tr","tr-0",{"children":[["$","td","td-0",{"children":["$","code","code-0",{"children":"dappName"}]}],["$","td","td-1",{"children":[["$","code","code-0",{"children":"string"}]," (optional)"]}],["$","td","td-2",{"children":"Your dApp's display name shown in the approval popup"}]]}],["$","tr","tr-1",{"children":[["$","td","td-0",{"children":["$","code","code-0",{"children":"requestedPermissions"}]}],["$","td","td-1",{"children":[["$","code","code-0",{"children":"string[]"}]," (optional)"]}],["$","td","td-2",{"children":"Permissions your dApp is requesting"}]]}]]}]]}],"\n",["$","p","p-6",{"children":[["$","strong","strong-0",{"children":"Returns:"}]," ",["$","code","code-0",{"children":"{ partyId: string }"}]]}],"\n",["$","h3","h3-1",{"children":["$","code","code-0",{"children":"disconnect()"}]}],"\n",["$","p","p-7",{"children":"Disconnect your dApp from the wallet."}],"\n",["$","pre","pre-3",{"children":["$","code","code-0",{"className":"language-javascript","children":"await window.cantonWallet.disconnect();\n"}]}],"\n",["$","h3","h3-2",{"children":["$","code","code-0",{"children":"isConnected()"}]}],"\n",["$","p","p-8",{"children":"Check if your dApp is currently connected to the wallet."}],"\n",["$","pre","pre-4",{"children":["$","code","code-0",{"className":"language-javascript","children":"const connected = await window.cantonWallet.isConnected();\n"}]}],"\n",["$","h3","h3-3",{"children":["$","code","code-0",{"children":"getPartyId()"}]}],"\n",["$","p","p-9",{"children":"Get the currently active party ID (requires existing connection)."}],"\n",["$","pre","pre-5",{"children":["$","code","code-0",{"className":"language-javascript","children":"const { partyId } = await window.cantonWallet.getPartyId();\n"}]}],"\n",["$","h3","h3-4",{"children":["$","code","code-0",{"children":"getBalances()"}]}],"\n",["$","p","p-10",{"children":"Get the balances for the currently active account."}],"\n",["$","pre","pre-6",{"children":["$","code","code-0",{"className":"language-javascript","children":"const balances = await window.cantonWallet.getBalances();\n"}]}],"\n",["$","h3","h3-5",{"children":["$","code","code-0",{"children":"signAndSubmit(transaction)"}]}],"\n",["$","p","p-11",{"children":"Submit a Daml command for the user to sign and execute on Canton."}],"\n",["$","pre","pre-7",{"children":["$","code","code-0",{"className":"language-javascript","children":"const result = await window.cantonWallet.signAndSubmit({\n  templateId: {\n    moduleName: 'Splice.Amulet',\n    entityName: 'TransferPreapproval',\n  },\n  choiceName: 'TransferPreapproval_Accept',\n  arguments: {\n    receiver: recipientPartyId,\n    amount: '100.0',\n  },\n});\n"}]}],"\n",["$","p","p-12",{"children":["When ",["$","code","code-0",{"children":"signAndSubmit"}]," is called, Zoff shows the user a signing popup with the full transaction details — template ID, choice, and arguments. The user must explicitly approve. Signing happens locally in the browser; only the signature is transmitted to the Canton participant node."]}],"\n",["$","p","p-13",{"children":["$","strong","strong-0",{"children":"Parameters:"}]}],"\n",["$","table","table-1",{"children":[["$","thead","thead-0",{"children":["$","tr","tr-0",{"children":[["$","th","th-0",{"children":"Field"}],["$","th","th-1",{"children":"Type"}],["$","th","th-2",{"children":"Description"}]]}]}],["$","tbody","tbody-0",{"children":[["$","tr","tr-0",{"children":[["$","td","td-0",{"children":["$","code","code-0",{"children":"templateId"}]}],["$","td","td-1",{"children":["$","code","code-0",{"children":"{ moduleName, entityName }"}]}],["$","td","td-2",{"children":"The Daml template to exercise"}]]}],["$","tr","tr-1",{"children":[["$","td","td-0",{"children":["$","code","code-0",{"children":"choiceName"}]}],["$","td","td-1",{"children":["$","code","code-0",{"children":"string"}]}],["$","td","td-2",{"children":"The choice to exercise on the template"}]]}],["$","tr","tr-2",{"children":[["$","td","td-0",{"children":["$","code","code-0",{"children":"arguments"}]}],["$","td","td-1",{"children":["$","code","code-0",{"children":"object"}]}],["$","td","td-2",{"children":"Choice arguments as key-value pairs"}]]}],["$","tr","tr-3",{"children":[["$","td","td-0",{"children":["$","code","code-0",{"children":"contractId"}]}],["$","td","td-1",{"children":[["$","code","code-0",{"children":"string"}]," (optional)"]}],["$","td","td-2",{"children":"Contract ID to exercise the choice on"}]]}]]}]]}],"\n",["$","p","p-14",{"children":[["$","strong","strong-0",{"children":"Returns:"}]," ",["$","code","code-0",{"children":"{ transactionId: string }"}]," on success."]}],"\n",["$","p","p-15",{"children":[["$","strong","strong-0",{"children":"Errors:"}]," If the user rejects the signing request, the promise rejects with error code ",["$","code","code-0",{"children":"4001"}]," (User Rejected)."]}],"\n",["$","h3","h3-6",{"children":"Event Listeners"}],"\n",["$","pre","pre-8",{"children":["$","code","code-0",{"className":"language-javascript","children":"// Listen for account changes (user switches active account)\nwindow.cantonWallet.on('accountChanged', (partyId) => {\n  console.log('Active account changed to:', partyId);\n});\n\n// Listen for disconnection\nwindow.cantonWallet.on('disconnect', () => {\n  console.log('Wallet disconnected');\n});\n\n// Remove a listener\nwindow.cantonWallet.off('accountChanged', myHandler);\n"}]}],"\n",["$","p","p-16",{"children":["Supported events: ",["$","code","code-0",{"children":"accountChanged"}],", ",["$","code","code-1",{"children":"disconnect"}],"."]}],"\n",["$","h2","h2-4",{"children":"Error Codes"}],"\n",["$","table","table-2",{"children":[["$","thead","thead-0",{"children":["$","tr","tr-0",{"children":[["$","th","th-0",{"children":"Code"}],["$","th","th-1",{"children":"Meaning"}]]}]}],["$","tbody","tbody-0",{"children":["$","tr","tr-0",{"children":[["$","td","td-0",{"children":["$","code","code-0",{"children":"4001"}]}],["$","td","td-1",{"children":"User rejected the request"}]]}]}]]}],"\n",["$","p","p-17",{"children":"Additional error codes may be added in future releases."}],"\n",["$","h2","h2-5",{"children":"Integration Example"}],"\n",["$","p","p-18",{"children":"A complete example connecting to Zoff and sending CC:"}],"\n",["$","pre","pre-9",{"children":["$","code","code-0",{"className":"language-javascript","children":"async function sendCC(recipientPartyId, amount) {\n  // 1. Ensure wallet is connected\n  const wallet = window.cantonWallet;\n  if (!wallet) throw new Error('Install Zoff Wallet');\n\n  const { partyId } = await wallet.connect();\n  console.log('Connected as:', partyId);\n\n  // 2. Submit a transfer\n  const result = await wallet.signAndSubmit({\n    templateId: {\n      moduleName: 'Splice.Amulet',\n      entityName: 'TransferPreapproval',\n    },\n    choiceName: 'TransferPreapproval_Accept',\n    arguments: {\n      receiver: recipientPartyId,\n      amount: amount.toString(),\n    },\n  });\n\n  console.log('Transfer submitted:', result.transactionId);\n  return result;\n}\n"}]}],"\n",["$","h2","h2-6",{"children":"React Hook (Example)"}],"\n",["$","pre","pre-10",{"children":["$","code","code-0",{"className":"language-typescript","children":"$f"}]}],"\n",["$","h2","h2-7",{"children":"Testing on DevNet"}],"\n",["$","p","p-19",{"children":"Zoff is currently deployed on Canton DevNet. To test your integration:"}],"\n",["$","ol","ol-0",{"children":["\n",["$","li","li-0",{"children":"Install the Zoff extension."}],"\n",["$","li","li-1",{"children":"Create a wallet (this allocates a DevNet party)."}],"\n",["$","li","li-2",{"children":"Your dApp should point to DevNet endpoints."}],"\n"]}],"\n",["$","p","p-20",{"children":"Mainnet integration will be available once Zoff receives mainnet credentials. The provider API is identical — no code changes needed on your end."}],"\n",["$","hr","hr-0",{}],"\n",["$","p","p-21",{"children":["Next: ",["$","a","a-0",{"href":"/docs/architecture","children":"Architecture Overview →"}]]}]]}]]}]
c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"name":"theme-color","content":"#1C1410"}],["$","meta","2",{"charSet":"utf-8"}],["$","title","3",{"children":"Developer Guide | Zoff Wallet"}],["$","meta","4",{"name":"description","content":"Self-custodial web wallet for Canton Network"}],["$","link","5",{"rel":"manifest","href":"/manifest.json","crossOrigin":"use-credentials"}],["$","meta","6",{"property":"og:title","content":"Zoff Wallet"}],["$","meta","7",{"property":"og:description","content":"Self-custodial web wallet for Canton Network"}],["$","meta","8",{"property":"og:site_name","content":"Zoff Wallet"}],["$","meta","9",{"property":"og:type","content":"website"}],["$","meta","10",{"name":"twitter:card","content":"summary"}],["$","meta","11",{"name":"twitter:title","content":"Zoff Wallet"}],["$","meta","12",{"name":"twitter:description","content":"Self-custodial web wallet for Canton Network"}],["$","link","13",{"rel":"icon","href":"/favicon.ico","sizes":"32x32"}],["$","link","14",{"rel":"icon","href":"/favicon.svg","type":"image/svg+xml"}],["$","link","15",{"rel":"apple-touch-icon","href":"/apple-touch-icon.png"}],["$","meta","16",{"name":"next-size-adjust"}]]
1:null
