Skip to content

Commit

Permalink
Merge pull request #1 from peterferguson/create-cross-origin-payment-…
Browse files Browse the repository at this point in the history
…credential

Create cross origin payment credential & First SPC call
  • Loading branch information
peterferguson authored Mar 16, 2024
2 parents c3e56f9 + b61d675 commit 20fda5c
Show file tree
Hide file tree
Showing 48 changed files with 5,943 additions and 129 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
**/.firebase
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
global.css,1710590178343,42d73ffbdad77a1b36c73186c8ecfedf609c52809da1ae37a2853a0dd10a91a2
favicon.svg,1710590178343,11f7bbcc36bf2f54c31744264fa1b24a0811ed62e4d26d5b18d3b2dec99040a7
_astro/create-payment-button.CINVb1iY.js,1710590178345,db69defc7d4eecb5b29b7fa206694342e57bed69e28954a4622b3c0112fab89a
_astro/hoisted.Dtw3UAUy.js,1710590178344,8f395373b0a398615502bc5d7b4630f3e0a2312777ddfdcf19854284d8dfe4d6
index.html,1710590178343,e287d0e9ce1e596069fe4eaffdf556d2ed9f40ee061e8ea03109b98c704d8172
_astro/index.NEDEFKed.js,1710590178344,c1250d9adcf7af9f08cbad6c8b34267ac3bd193c676424dc5653db6fc9505e90
_astro/utils.CR3g-f2u.js,1710590178344,c953e34917739c011debb7b1c24907478e139d6bc5d139b3d99a2ba45fed48c3
_astro/client.DbokQZWz.js,1710590178345,dfc9d946776d09a6ecd38cb440df7115dce93ec392f2272238dc903ac9f14163
9 changes: 9 additions & 0 deletions apps/dapp/.firebase/spc-dapp/hosting/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions apps/dapp/.firebase/spc-dapp/hosting/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!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><script type="module" src="/_astro/hoisted.Dtw3UAUy.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]"> <!-- <form
id="form"
action={`${paymentOrigin}/`}
class="center"
target="iframe"
method="post"
> --> <h1>SPC dApp</h1> <div id="iframe-container" class="hidden"> <iframe name="iframe" allow="payment https://spc-wallet.web.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.CINVb1iY.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> <!-- </form> --> </main> </body> </html>
5 changes: 5 additions & 0 deletions apps/dapp/.firebaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"projects": {
"default": "spc-dapp"
}
}
4 changes: 2 additions & 2 deletions apps/dapp/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}
18 changes: 9 additions & 9 deletions apps/dapp/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}
16 changes: 7 additions & 9 deletions apps/dapp/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
# Astro Starter Kit: Minimal
# Secure Payment Confirmation (SPC)-Enabled dApp

```sh
npm create astro@latest -- --template minimal
```

[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/minimal)
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/astro/tree/latest/examples/minimal)
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/withastro/astro?devcontainer_path=.devcontainer/minimal/devcontainer.json)
## 💡 Idea

> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
SPC is a browser native API that is designed to streamline payments on the web. It's purpose is to streamline the UX for
authneticating users across merchants (in web3 think dApps) whilst verifiying cryptographically that the user can pay
for a transaction with their payment provider (think wallet). The protocol is built on-top of webauthn in order to
provide the cryptographic proof that the user indeed is the one that initiated the transaction.

## 🚀 Project Structure
## The Project Structure

Inside of your Astro project, you'll see the following folders and files:

Expand Down
16 changes: 14 additions & 2 deletions apps/dapp/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
import { defineConfig } from 'astro/config';
import { defineConfig } from "astro/config";
import tailwind from "@astrojs/tailwind";
import react from "@astrojs/react";

import node from "@astrojs/node";

// https://astro.build/config
export default defineConfig({});
export default defineConfig({
// output: 'server',
integrations: [tailwind({
applyBaseStyles: false
}), react()],
adapter: node({
mode: "standalone"
})
});
17 changes: 17 additions & 0 deletions apps/dapp/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "public/global.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
9 changes: 9 additions & 0 deletions apps/dapp/firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"hosting": {
"source": ".",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"frameworksBackend": {
"region": "europe-west1"
}
}
}
46 changes: 31 additions & 15 deletions apps/dapp/package.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
{
"name": "dapp",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro check && astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"astro": "^4.5.4",
"@astrojs/check": "^0.5.9",
"typescript": "^5.4.2"
}
"name": "dapp",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev --port 4321 & npx localtunnel --port 4321 -s spc-dapp",
"start": "astro dev",
"build": "astro check && astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/check": "^0.5.9",
"@astrojs/node": "^8.2.3",
"@astrojs/react": "^3.1.0",
"@astrojs/tailwind": "^5.1.0",
"@radix-ui/react-slot": "^1.0.2",
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
"astro": "^4.5.4",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"firebase-tools": "^13.5.1",
"helpers": "workspace:*",
"lucide-react": "^0.358.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwind-merge": "^2.2.1",
"tailwindcss": "^3.4.1",
"tailwindcss-animate": "^1.0.7",
"typescript": "^5.4.2"
}
}
76 changes: 76 additions & 0 deletions apps/dapp/public/global.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;

--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;

--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;

--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;

--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;

--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;

--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;

--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;

--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;

--radius: 0.5rem;
}

.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;

--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;

--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;

--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;

--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;

--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;

--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;

--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;

--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;
}
}

@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
27 changes: 27 additions & 0 deletions apps/dapp/src/components/create-payment-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Button } from "@/components/ui/button";
import { payWithSPC } from "@/lib/utils";

export function CreatePaymentButton() {
return (
<Button
onClick={async (e) => {
e.preventDefault();
console.log("Creating payment");
await payWithSPC(
{
allowedCredentials: ["l8S4J0LWhvVdabcKL9tJcOApr5Qp44bi3SH88YCTOjQ"],
challenge: "challenge",
timeout: 60000,
},
{
currency: "USDC",
value: "100.00",
},
"0x",
);
}}
>
Create Payment
</Button>
);
}
56 changes: 56 additions & 0 deletions apps/dapp/src/components/ui/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";

import { cn } from "@/lib/utils";

const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
);

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
);
},
);
Button.displayName = "Button";

export { Button, buttonVariants };
Loading

0 comments on commit 20fda5c

Please sign in to comment.