Skip to content

Commit

Permalink
Merge pull request #6 from peterferguson/feat/deploy-smart-account
Browse files Browse the repository at this point in the history
add relay function to deploy on register
  • Loading branch information
peterferguson authored Mar 17, 2024
2 parents 3667dee + 71609e0 commit d8eb2e0
Show file tree
Hide file tree
Showing 11 changed files with 174 additions and 125 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
favicon.svg,1710612600596,11f7bbcc36bf2f54c31744264fa1b24a0811ed62e4d26d5b18d3b2dec99040a7
global.css,1710612600596,42d73ffbdad77a1b36c73186c8ecfedf609c52809da1ae37a2853a0dd10a91a2
index.html,1710612600596,4f4375b1d8a51aa512086a8597622b47c35c025491a244381d86050a6de93acd
_astro/hoisted.bU3TEY26.js,1710612600597,12298e4f606a273f1d1d5645e995b3f08bf59eb700b3581f4e2978abb27ab38a
_astro/create-payment-button.CE6C2yQc.js,1710612600598,12a2a4c61d23bc3d87b947c3202cb6a457bf9fa0b7b91087f1bf9cc339644c82
_astro/index.8-_CQqnL.css,1710612600597,e9c06675410edad1a5e1e4185fe3e9c9a0002f94035f81189fe63e262c734447
_astro/index.NEDEFKed.js,1710612600597,c1250d9adcf7af9f08cbad6c8b34267ac3bd193c676424dc5653db6fc9505e90
_astro/constants.Bq4ER0LB.js,1710612600598,15319ae0b9cb6cac4168d89ce7618a53261b798b6ae301b81bdb49ae48ec7f75
_astro/client.DbokQZWz.js,1710612600598,dfc9d946776d09a6ecd38cb440df7115dce93ec392f2272238dc903ac9f14163
favicon.svg,1710628059222,11f7bbcc36bf2f54c31744264fa1b24a0811ed62e4d26d5b18d3b2dec99040a7
global.css,1710628059221,42d73ffbdad77a1b36c73186c8ecfedf609c52809da1ae37a2853a0dd10a91a2
_astro/button.cJ5DMypp.js,1710628059238,701808af954e14b33f962b51f6e71219536ea2f4b20b1ae61e0b928558367598
index.html,1710628059220,87bd370988cdc70e3b2b51c75edaeeb78445e41a8a7ab17f79d566309f88c728
_astro/constants.k50eM4pa.js,1710628059236,8fa9491ca1e640ee55957b77b7f3cb56d3b4fcc5cedf90ce245ccb6acecf08ea
_astro/create-payment-button.DS5N7mqO.js,1710628059229,0fd224ff01eb02fb4d86f2a4d0b59a1c150993b1c8a0c4cb689a551d277a47f3
_astro/hoisted.Cf8LOESL.js,1710628059225,0c5166f31ddce70fa8cd3f0acbf876e43801022e909780dd31a3ceed67dfc527
_astro/deploy-account-button.C4nwBoNT.js,1710628059225,de0abc549a0542a1f9aa88884a09575627da66f5a42b441711022b24ccb4c9ae
_astro/ccip.k6LiPXKt.js,1710628059238,001401e4836946326c7acfec5536a5decec22a0d79faa562acc13a78ed42003f
_astro/index.B7M7nzP-.css,1710628059224,76d1450f2c130d36cad17f351a69c9da2171b7c163a4e367ee22ced3de72c868
_astro/index.NEDEFKed.js,1710628059224,c1250d9adcf7af9f08cbad6c8b34267ac3bd193c676424dc5653db6fc9505e90
_astro/utils.DVs8iIlu.js,1710628059223,d2970d868c60c379893e77a2ee97083d0e04922da4e5ffc08dfd617667c282ad
_astro/client.DbokQZWz.js,1710628059237,dfc9d946776d09a6ecd38cb440df7115dce93ec392f2272238dc903ac9f14163
_astro/deploy-account-button.BbVFG_Xp.js,1710628059226,8a5b39bd352c3286e80ab2b238f63f41315da2f19e3f4ef6dbe7180ae716d2ff
2 changes: 1 addition & 1 deletion apps/dapp/.firebase/spc-dapp/hosting/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!DOCTYPE html><html lang="en"> <head><meta charset="utf-8"><link rel="icon" type="image/svg+xml" href="/favicon.svg"><link rel="stylesheet" href="/global.css"><meta name="viewport" content="width=device-width"><meta name="generator" content="Astro v4.5.4"><title>SPC dApp</title><link rel="stylesheet" href="/_astro/index.8-_CQqnL.css" /><script type="module" src="/_astro/hoisted.bU3TEY26.js"></script></head> <body class="flex flex-col items-center justify-center h-screen"> <main class="flex flex-col items-center justify-evenly min-h-[20vh]"> <h1>SPC dApp</h1> <dialog id="wallet-iframe-dialog" class="items-center justify-center border rounded-lg py-3 px-4 min-h-[40vh] backdrop:bg-black backdrop:opacity-50 backdrop:backdrop-blur-md backdrop:transition-opacity backdrop:duration-300"> <iframe class="min-h-[40vh] border-0 m-0" name="iframe" allow="payment https://spc-wallet.vercel.app"></iframe> </dialog> <style>astro-island,astro-slot,astro-static-slot{display:contents}</style><script>(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).only=e;window.dispatchEvent(new Event("astro:only"));})();;(()=>{var v=Object.defineProperty;var A=(c,s,a)=>s in c?v(c,s,{enumerable:!0,configurable:!0,writable:!0,value:a}):c[s]=a;var d=(c,s,a)=>(A(c,typeof s!="symbol"?s+"":s,a),a);var u;{let c={0:t=>m(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t)},s=t=>{let[e,n]=t;return e in c?c[e](n):void 0},a=t=>t.map(s),m=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([e,n])=>[e,s(n)]));customElements.get("astro-island")||customElements.define("astro-island",(u=class extends HTMLElement{constructor(){super(...arguments);d(this,"Component");d(this,"hydrator");d(this,"hydrate",async()=>{var f;if(!this.hydrator||!this.isConnected)return;let e=(f=this.parentElement)==null?void 0:f.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let n=this.querySelectorAll("astro-slot"),r={},l=this.querySelectorAll("template[data-astro-template]");for(let o of l){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(r[o.getAttribute("data-astro-template")||"default"]=o.innerHTML,o.remove())}for(let o of n){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(r[o.getAttribute("name")||"default"]=o.innerHTML)}let h;try{h=this.hasAttribute("props")?m(JSON.parse(this.getAttribute("props"))):{}}catch(o){let i=this.getAttribute("component-url")||"<unknown>",b=this.getAttribute("component-export");throw b&&(i+=` (export ${b})`),console.error(`[hydrate] Error parsing props for component ${i}`,this.getAttribute("props"),o),o}let p;await this.hydrator(this)(this.Component,h,r,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});d(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),n.disconnect(),this.childrenConnectedCallback()},n=new MutationObserver(()=>{var r;((r=this.lastChild)==null?void 0:r.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});n.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),n=this.getAttribute("client");if(Astro[n]===void 0){window.addEventListener(`astro:${n}`,()=>this.start(),{once:!0});return}try{await Astro[n](async()=>{let r=this.getAttribute("renderer-url"),[l,{default:h}]=await Promise.all([import(this.getAttribute("component-url")),r?import(r):()=>()=>{}]),p=this.getAttribute("component-export")||"default";if(!p.includes("."))this.Component=l[p];else{this.Component=l;for(let y of p.split("."))this.Component=this.Component[y]}return this.hydrator=h,this.hydrate},e,this)}catch(r){console.error(`[astro-island] Error hydrating ${this.getAttribute("component-url")}`,r)}}attributeChangedCallback(){this.hydrate()}},d(u,"observedAttributes",["props"]),u))}})();</script><astro-island uid="1iICUQ" component-url="/_astro/create-payment-button.CE6C2yQc.js" component-export="CreatePaymentButton" renderer-url="/_astro/client.DbokQZWz.js" props="{}" ssr="" client="only" opts="{&quot;name&quot;:&quot;CreatePaymentButton&quot;,&quot;value&quot;:true}"></astro-island> </main> </body> </html>
<!DOCTYPE html><html lang="en"> <head><meta charset="utf-8"><link rel="icon" type="image/svg+xml" href="/favicon.svg"><link rel="stylesheet" href="/global.css"><meta name="viewport" content="width=device-width"><meta name="generator" content="Astro v4.5.4"><title>SPC dApp</title><link rel="stylesheet" href="/_astro/index.B7M7nzP-.css" /><script type="module" src="/_astro/hoisted.Cf8LOESL.js"></script></head> <body class="flex flex-col items-center justify-center h-screen"> <main class="flex flex-col items-center justify-evenly min-h-[20vh]"> <h1>SPC dApp</h1> <div id="iframe-container" class="hidden"> <iframe name="iframe" allow="payment https://spc-wallet.vercel.app"></iframe> </div> <style>astro-island,astro-slot,astro-static-slot{display:contents}</style><script>(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).only=e;window.dispatchEvent(new Event("astro:only"));})();;(()=>{var v=Object.defineProperty;var A=(c,s,a)=>s in c?v(c,s,{enumerable:!0,configurable:!0,writable:!0,value:a}):c[s]=a;var d=(c,s,a)=>(A(c,typeof s!="symbol"?s+"":s,a),a);var u;{let c={0:t=>m(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t)},s=t=>{let[e,n]=t;return e in c?c[e](n):void 0},a=t=>t.map(s),m=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map(([e,n])=>[e,s(n)]));customElements.get("astro-island")||customElements.define("astro-island",(u=class extends HTMLElement{constructor(){super(...arguments);d(this,"Component");d(this,"hydrator");d(this,"hydrate",async()=>{var f;if(!this.hydrator||!this.isConnected)return;let e=(f=this.parentElement)==null?void 0:f.closest("astro-island[ssr]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let n=this.querySelectorAll("astro-slot"),r={},l=this.querySelectorAll("template[data-astro-template]");for(let o of l){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(r[o.getAttribute("data-astro-template")||"default"]=o.innerHTML,o.remove())}for(let o of n){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(r[o.getAttribute("name")||"default"]=o.innerHTML)}let h;try{h=this.hasAttribute("props")?m(JSON.parse(this.getAttribute("props"))):{}}catch(o){let i=this.getAttribute("component-url")||"<unknown>",b=this.getAttribute("component-export");throw b&&(i+=` (export ${b})`),console.error(`[hydrate] Error parsing props for component ${i}`,this.getAttribute("props"),o),o}let p;await this.hydrator(this)(this.Component,h,r,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});d(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),n.disconnect(),this.childrenConnectedCallback()},n=new MutationObserver(()=>{var r;((r=this.lastChild)==null?void 0:r.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});n.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),n=this.getAttribute("client");if(Astro[n]===void 0){window.addEventListener(`astro:${n}`,()=>this.start(),{once:!0});return}try{await Astro[n](async()=>{let r=this.getAttribute("renderer-url"),[l,{default:h}]=await Promise.all([import(this.getAttribute("component-url")),r?import(r):()=>()=>{}]),p=this.getAttribute("component-export")||"default";if(!p.includes("."))this.Component=l[p];else{this.Component=l;for(let y of p.split("."))this.Component=this.Component[y]}return this.hydrator=h,this.hydrate},e,this)}catch(r){console.error(`[astro-island] Error hydrating ${this.getAttribute("component-url")}`,r)}}attributeChangedCallback(){this.hydrate()}},d(u,"observedAttributes",["props"]),u))}})();</script><astro-island uid="1iICUQ" component-url="/_astro/create-payment-button.DS5N7mqO.js" component-export="CreatePaymentButton" renderer-url="/_astro/client.DbokQZWz.js" props="{}" ssr="" client="only" opts="{&quot;name&quot;:&quot;CreatePaymentButton&quot;,&quot;value&quot;:true}"></astro-island> <astro-island uid="Z1D4B9H" component-url="/_astro/deploy-account-button.C4nwBoNT.js" component-export="DeployAccountButton" renderer-url="/_astro/client.DbokQZWz.js" props="{}" ssr="" client="only" opts="{&quot;name&quot;:&quot;DeployAccountButton&quot;,&quot;value&quot;:true}"></astro-island> <!-- </form> --> <dialog id="wallet-iframe-dialog" class="items-center justify-center border rounded-lg py-3 px-4 min-h-[40vh] backdrop:bg-black backdrop:opacity-50 backdrop:backdrop-blur-md backdrop:transition-opacity backdrop:duration-300"> <iframe class="min-h-[40vh] border-0 m-0" name="iframe" allow="payment https://spc-wallet.vercel.app"></iframe> </dialog> <astro-island uid="1iICUQ" component-url="/_astro/create-payment-button.DS5N7mqO.js" component-export="CreatePaymentButton" renderer-url="/_astro/client.DbokQZWz.js" props="{}" ssr="" client="only" opts="{&quot;name&quot;:&quot;CreatePaymentButton&quot;,&quot;value&quot;:true}"></astro-island> </main> </body> </html>
16 changes: 0 additions & 16 deletions apps/dapp/src/components/deploy-account-button.tsx

This file was deleted.

72 changes: 14 additions & 58 deletions apps/dapp/src/lib/permissionless.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,26 @@
import { createBundlerClient, createSmartAccountClient } from "permissionless"
import { baseSepolia } from "viem/chains"
import { createPublicClient, createWalletClient, http } from "viem"
import { createPimlicoPaymasterClient } from "permissionless/clients/pimlico";
import { privateKeyToSimpleSmartAccount, signerToSafeSmartAccount } from "permissionless/accounts";
import { privateKeyToAccount } from "viem/accounts";
import { createBundlerClient } from "permissionless";
import { createPublicClient, http } from "viem";
import { baseSepolia } from "viem/chains";

// ! Dont do this in prod
const pimlicoApiKey = import.meta.env.PUBLIC_PIMLICO_API_KEY
const privateKey = import.meta.env.PUBLIC_PRIVATE_KEY
const pimlicoApiKey = import.meta.env.PUBLIC_PIMLICO_API_KEY;

const pimlicoTransport = (version: 'v1' | 'v2') => http(`https://api.pimlico.io/${version}/${baseSepolia.id}/rpc?apikey=${pimlicoApiKey}`)
const pimlicoTransport = (version: "v1" | "v2") =>
http(
`https://api.pimlico.io/${version}/${baseSepolia.id}/rpc?apikey=${pimlicoApiKey}`,
);

export const ENTRYPOINT_ADDRESS_V07 = '0x0000000071727De22E5E9d8BAf0edAc6f37da032';
export const ENTRYPOINT_ADDRESS_V06 = '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789';
export const ENTRYPOINT_ADDRESS_V07 =
"0x0000000071727De22E5E9d8BAf0edAc6f37da032";

// create clients --------------------------------------------

export const publicClient = createPublicClient({
transport: http(baseSepolia.rpcUrls.default.http[0])
});

export const walletClient = createWalletClient({
chain: baseSepolia,
transport: http(baseSepolia.rpcUrls.default.http[0]),
account: privateKeyToAccount(privateKey)
transport: http(baseSepolia.rpcUrls.default.http[0]),
});

export const bundlerClient = createBundlerClient({
chain: baseSepolia,
transport: pimlicoTransport('v2'),
entryPoint: ENTRYPOINT_ADDRESS_V07
})

export const paymasterClient = createPimlicoPaymasterClient({
transport: pimlicoTransport('v2'),
entryPoint: ENTRYPOINT_ADDRESS_V06
chain: baseSepolia,
transport: pimlicoTransport("v2"),
entryPoint: ENTRYPOINT_ADDRESS_V07,
});

// create account & account client --------------------------------------------

export const simpleAccount = await privateKeyToSimpleSmartAccount(publicClient, {
privateKey: privateKey,
factoryAddress: "0x15Ba39375ee2Ab563E8873C8390be6f2E2F50232",
entryPoint: ENTRYPOINT_ADDRESS_V07
});

export const safeAccount = await signerToSafeSmartAccount(publicClient, {
entryPoint: ENTRYPOINT_ADDRESS_V06,
signer: privateKeyToAccount(privateKey),
saltNonce: 0n, // optional
safeVersion: "1.4.1",
//address: "0x...", // optional, only if you are using an already created account
})

export const smartAccountClient = createSmartAccountClient({
account: simpleAccount,
entryPoint: ENTRYPOINT_ADDRESS_V07,
chain: baseSepolia,
bundlerTransport: pimlicoTransport('v2'),
});

export const safeAccountClient = createSmartAccountClient({
account: safeAccount,
entryPoint: ENTRYPOINT_ADDRESS_V06,
chain: baseSepolia,
bundlerTransport: pimlicoTransport('v2'),
});


34 changes: 0 additions & 34 deletions apps/dapp/src/lib/safe-account.ts

This file was deleted.

7 changes: 1 addition & 6 deletions apps/dapp/src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
---
import "../../public/global.css";
import { CreatePaymentButton } from "@/components/create-payment-button";
import { DeployAccountButton } from "@/components/deploy-account-button";
import { getPaymentOrigin } from "@/lib/utils";
const paymentOrigin = getPaymentOrigin();
Expand All @@ -22,13 +21,9 @@ import WalletIframeDialog from "@/components/wallet-iframe-dialog.astro";
<h1>SPC dApp</h1>

<div id="iframe-container" class="hidden">
<iframe name="iframe" allow={`payment ${paymentOrigin}`}
></iframe>
<iframe name="iframe" allow={`payment ${paymentOrigin}`}></iframe>
</div>

<CreatePaymentButton client:only />
<DeployAccountButton client:only />
<!-- </form> -->
<WalletIframeDialog />
<CreatePaymentButton client:only />
</main>
Expand Down
2 changes: 2 additions & 0 deletions apps/wallet/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@
"firebase-tools": "^13.5.1",
"helpers": "workspace:*",
"lucide-react": "^0.358.0",
"permissionless": "^0.1.10",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.51.0",
"tailwind-merge": "^2.2.1",
"tailwindcss": "^3.4.1",
"tailwindcss-animate": "^1.0.7",
"typescript": "^5.4.2",
"viem": "^2.8.10",
"zod": "^3.22.4"
}
}
22 changes: 21 additions & 1 deletion apps/wallet/src/components/forms/username.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,30 @@ export function UsernameForm() {
}
}

await registerSpcCredential({
const registrationResponse = await registerSpcCredential({
username,
challenge: "challenge",
});

if (!registrationResponse.ok) {
console.error("Failed to register credential", registrationResponse);
return;
}

// TODO: @jamesmccomish please add a description for this route handler ... why we need to deploy from a relay instead of
// TODO: using init code
const deployResponse = await fetch("/relay/deploy", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ username }),
});

const { txHash, address } = (await deployResponse.json()) ?? {};

console.log("deployResponse", { txHash, address });

if (txHash) localStorage.setItem("deployTxHash", txHash);
if (address) localStorage.setItem("address", address);
}

return (
Expand Down
Loading

0 comments on commit d8eb2e0

Please sign in to comment.