@moneypot/hub 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -62
- package/dist/dashboard/assets/{index-BtrbrisP.js → index-Tqyvm1Se.js} +1 -1
- package/dist/dashboard/index.html +1 -1
- package/dist/src/plugins/hub-add-casino.js +10 -5
- package/package.json +2 -2
- package/dist/src/plugins/caas-add-casino.d.ts +0 -1
- package/dist/src/plugins/caas-add-casino.js +0 -150
- package/dist/src/plugins/caas-authenticate.d.ts +0 -1
- package/dist/src/plugins/caas-authenticate.js +0 -175
- package/dist/src/plugins/caas-balance-alert.d.ts +0 -1
- package/dist/src/plugins/caas-balance-alert.js +0 -43
- package/dist/src/plugins/caas-claim-faucet.d.ts +0 -1
- package/dist/src/plugins/caas-claim-faucet.js +0 -85
- package/dist/src/plugins/caas-current-x.d.ts +0 -1
- package/dist/src/plugins/caas-current-x.js +0 -62
- package/dist/src/plugins/caas-schema-prefix.d.ts +0 -1
- package/dist/src/plugins/caas-schema-prefix.js +0 -25
- package/dist/src/plugins/caas-user-balance-by-currency.d.ts +0 -1
- package/dist/src/plugins/caas-user-balance-by-currency.js +0 -55
- package/dist/src/plugins/caas-withdraw.d.ts +0 -1
- package/dist/src/plugins/caas-withdraw.js +0 -133
package/README.md
CHANGED
|
@@ -44,65 +44,3 @@ startAndListen(options)
|
|
|
44
44
|
})
|
|
45
45
|
.catch(console.error);
|
|
46
46
|
```
|
|
47
|
-
|
|
48
|
-
## Development
|
|
49
|
-
|
|
50
|
-
To work on this library , there's a mini project in the `./demo` directory that uses `@moneypot/hub` as a lib.
|
|
51
|
-
|
|
52
|
-
```sh
|
|
53
|
-
createdb hub_demo
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
Ensure this role exists:
|
|
57
|
-
|
|
58
|
-
```sql
|
|
59
|
-
CREATE ROLE app_postgraphile LOGIN PASSWORD 'pass';
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Create `.env`:
|
|
63
|
-
|
|
64
|
-
```ini
|
|
65
|
-
DATABASE_URL="postgres://app_postgraphile:pass@localhost/hub_demo"
|
|
66
|
-
SUPERUSER_DATABASE_URL="postgres://app_superuser:pass@localhost/hub_demo"
|
|
67
|
-
GRAPHILE_ENV=development
|
|
68
|
-
NODE_ENV=development
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Run the demo:
|
|
72
|
-
|
|
73
|
-
```sh
|
|
74
|
-
cd demo
|
|
75
|
-
npm install
|
|
76
|
-
npm run dev
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
The hub-demo server should be running at <http://localhost:8888/graphql>.
|
|
80
|
-
|
|
81
|
-
### Dashboard development
|
|
82
|
-
|
|
83
|
-
To work on the `./dashboard` react app, ensure that hub-demo is running.
|
|
84
|
-
|
|
85
|
-
Terminal 1: Run demo controller inside this repo's `demo` dir:
|
|
86
|
-
|
|
87
|
-
```sh
|
|
88
|
-
cd demo
|
|
89
|
-
npm install
|
|
90
|
-
npm run dev
|
|
91
|
-
# Listening on :8888
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
Terminal 2: Run dashboard project pointed at demo controller
|
|
95
|
-
|
|
96
|
-
```
|
|
97
|
-
cd dashboard
|
|
98
|
-
npm install
|
|
99
|
-
VITE_GRAPHQL_URL=http://localhost:8888/graphql npm run dev
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Now visit the localhost url that it prints out.
|
|
103
|
-
|
|
104
|
-
(The `VITE_GRAPHQL_URL` override is necessary since the dashboard defaults to `window.location.origin + "/graphql"` as its api endpoint since it usually runs bundled with the hub server.)
|
|
105
|
-
|
|
106
|
-
## Change log
|
|
107
|
-
|
|
108
|
-
- 1.0.0: Initial release.
|
|
@@ -176,7 +176,7 @@ attempted value: ${c}
|
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
|
-
`),Tz={name:"moneypot.dev",baseUrl:"https://moneypot.dev",graphqlUrl:"https://api.moneypot.dev/graphql",apiKey:""},wz=wo().shape({name:ld().required(),baseUrl:E1().required(),graphqlUrl:b1().required(),apiKey:_z().required()}),Az=zt(({show:e,onHide:t})=>{const r=sn(),[i]=Hx(r,{document:Oz}),u=id({initialValues:Tz,validationSchema:wz,onSubmit:async(c,{setSubmitting:h,setStatus:d})=>(d(null),h(!0),i({variables:{input:{name:c.name,baseUrl:c.baseUrl,graphqlUrl:c.graphqlUrl,apiKey:c.apiKey}}}).then(m=>{var E;((E=m.hubAddCasino)==null?void 0:E.casino)&&(r.refetchCasinos(),t())}).catch(m=>{d(Bn(m))}).finally(()=>{h(!1)}))});return v.jsx(It,{show:e,onHide:t,size:"lg",children:v.jsxs(Ve,{onSubmit:u.handleSubmit,children:[v.jsx(It.Header,{closeButton:!0,children:v.jsx(It.Title,{children:"Add Casino"})}),v.jsxs(It.Body,{children:[u.status&&v.jsx(ur,{variant:"danger",className:"mb-3",children:u.status}),v.jsxs("fieldset",{disabled:u.isSubmitting,children:[v.jsxs(Ve.Group,{children:[v.jsx(Ve.Label,{children:"Name (for your own reference)"}),v.jsx(Ve.Control,{type:"text",name:"name",placeholder:"Ex: moneypot.dev",value:u.values.name,onChange:u.handleChange,onBlur:u.handleBlur,isInvalid:u.touched.name&&!!u.errors.name}),v.jsx(Ve.Control.Feedback,{type:"invalid",children:u.errors.name})]}),v.jsxs(Ve.Group,{className:"mt-2",children:[v.jsx(Ve.Label,{children:"Website base URL"}),v.jsx(Ve.Control,{type:"text",name:"baseUrl",placeholder:"Ex: https://moneypot.dev",value:u.values.baseUrl,onChange:u.handleChange,onBlur:u.handleBlur,isInvalid:u.touched.baseUrl&&!!u.errors.baseUrl}),v.jsx(Ve.Control.Feedback,{type:"invalid",children:u.errors.baseUrl})]}),v.jsxs(Ve.Group,{className:"mt-2",children:[v.jsx(Ve.Label,{children:"GraphQL URL"}),v.jsx(Ve.Control,{type:"text",name:"graphqlUrl",placeholder:"Ex: https://api.moneypot.dev/graphql",value:u.values.graphqlUrl,onChange:u.handleChange,onBlur:u.handleBlur,isInvalid:u.touched.graphqlUrl&&!!u.errors.graphqlUrl}),v.jsx(Ve.Control.Feedback,{type:"invalid",children:u.errors.graphqlUrl})]}),v.jsxs(Ve.Group,{className:"mt-2",children:[v.jsxs(Ve.Label,{children:["API Key"," ",v.jsx(xz,{text:"This should be a valid api key that you created for your controller on the casino website"})]}),v.jsx(Ve.Control,{type:"text",name:"apiKey",placeholder:"Ex: 01234567-89ab-cdef-0123-456789abcdef",value:u.values.apiKey,onChange:u.handleChange,onBlur:u.handleBlur,isInvalid:u.touched.apiKey&&!!u.errors.apiKey}),v.jsx(Ve.Control.Feedback,{type:"invalid",children:u.errors.apiKey})]})]})]}),v.jsx(It.Footer,{children:v.jsx(Qt,{type:"submit",disabled:u.isSubmitting,children:u.isSubmitting?"Testing...":"Test connection and save"})})]})})}),Nz=zt(()=>{var i;const e=sn(),[t,r]=b.useState(!1);return v.jsxs("div",{children:[v.jsx(Az,{show:t,onHide:()=>r(!1)}),v.jsxs("h2",{children:["Casinos",v.jsx(Qt,{className:"float-end",onClick:()=>r(!0),children:"Add casino"})]}),v.jsxs(_i,{striped:!0,bordered:!0,hover:!0,children:[v.jsx("thead",{children:v.jsxs("tr",{children:[v.jsx("th",{children:"ID"}),v.jsx("th",{children:"Name"}),v.jsx("th",{children:"Base URL"}),v.jsx("th",{children:"GraphQL URL"}),v.jsx("th",{children:"Added"})]})}),v.jsx("tbody",{children:(i=e.loggedIn)==null?void 0:i.casinos.map(l=>v.jsxs("tr",{children:[v.jsx("td",{children:v.jsx($n,{to:`/casinos/${l.id}`,children:l.id})}),v.jsx("td",{children:l.name}),v.jsxs("td",{style:{whiteSpace:"nowrap"},children:[v.jsx("span",{className:"user-select-all",children:l.baseUrl})," ",v.jsx("a",{href:l.baseUrl,target:"_blank",rel:"noreferrer",className:"text-decoration-none",children:v.jsx(Gm,{style:{verticalAlign:"baseline"}})})]}),v.jsxs("td",{style:{whiteSpace:"nowrap"},children:[v.jsx("span",{className:"user-select-all",children:l.graphqlUrl})," ",v.jsx("a",{href:l.graphqlUrl,target:"_blank",rel:"noreferrer",className:"text-decoration-none",children:v.jsx(Gm,{style:{verticalAlign:"baseline"}})})]}),v.jsx("td",{children:v.jsx(Da,{date:El(l.id),variant:"long"})})]},l.id))})]})]})});function Oi(){var i,l;const{casinoId:e}=j_(),t=sn();return b.useEffect(()=>{var u;e&&!((u=t.loggedIn)!=null&&u.casinos.find(c=>c.id===e))&&console.warn(`Casino ${e} not found`)},[e,(i=t.loggedIn)==null?void 0:i.casinos]),((l=t.loggedIn)==null?void 0:l.casinos.find(u=>u.id===e))||null}const v_=[{path:"",title:"Casino"},{path:"users",title:"Users"},{path:"experiences",title:"Experiences"},{path:"bankrolls",title:"Bankrolls"},{path:"currencies",title:"Currencies"},{path:"deposits",title:"Deposits"},{path:"withdrawals",title:"Withdrawals"},{path:"jwks",title:"Pubkeys"}];function Cz(e,t){return e.sort((r,i)=>i.length-r.length).find(r=>t.includes("/"+r))}const Rz=zt(()=>{var h;const e=ka(),t=sn(),r=Mf(),i=Oi();if(!t.loggedIn)return v.jsx("div",{children:"You must be logged in"});if(!i)return v.jsx(Yr,{});const l=Cz(v_.map(d=>d.path),e.pathname),u=e.pathname.match(/^\/casinos\/[^/]+/),c=d=>{var E;if(!u)return;const m=d.target.value,y=(E=t.loggedIn)==null?void 0:E.casinos.find(g=>g.id===m);y&&r(e.pathname.replace(/\/casinos\/[^/]+/,`/casinos/${y.id}`))};return v.jsxs("div",{children:[v.jsxs(bT,{direction:"horizontal",style:{alignItems:"baseline"},children:[v.jsxs(Ip,{children:[v.jsx(Ip.Item,{linkAs:$n,linkProps:{to:"/casinos"},children:"Casinos"}),v.jsx(Ip.Item,{active:!0,children:i.name})]}),v.jsxs(Ve.Select,{className:"ms-2 d-inline-block",style:{width:"auto"},size:"sm",value:i.id,onChange:c,children:[v.jsx("option",{disabled:!0,children:"Select casino"}),(h=t.loggedIn)==null?void 0:h.casinos.map(d=>v.jsx("option",{value:d.id,children:d.name},d.id))]})]}),v.jsx("ul",{className:"nav nav-tabs mb-4 ",children:v_.map(d=>v.jsx("li",{className:"nav-item",children:v.jsx($n,{to:d.path,className:`nav-link ${l===d.path?"active":""}`,children:d.title})},d.path))}),v.jsx(M_,{})]})}),vi=({text:e,sourceRef:t,popoverDuration:r=1e3,popoverPlacement:i="top"})=>{const[l,u]=b.useState("idle"),[c,h]=b.useState(!1),[d,m]=b.useState("success"),y=b.useRef(null),E=b.useRef(null),g=b.useRef(null);b.useEffect(()=>()=>{y.current&&clearTimeout(y.current),E.current&&clearTimeout(E.current)},[]);const _=x=>{m(x),h(!0),E.current&&clearTimeout(E.current),E.current=setTimeout(()=>{h(!1)},r)},T=()=>{y.current&&clearTimeout(y.current),navigator.clipboard.writeText(e).then(()=>{u("success"),y.current=setTimeout(()=>u("idle"),r),_("success")}).catch(x=>{console.error("Failed to copy text: ",x),u("error"),y.current=setTimeout(()=>u("idle"),r),_("error")})},N=()=>{switch(l){case"success":return v.jsx(Km,{className:"text-success-emphasis"});case"error":return v.jsx(Jm,{className:"text-danger-emphasis"});default:return v.jsx(u1,{})}},A=()=>d==="success"?"Copied!":"Error";return v.jsxs(v.Fragment,{children:[v.jsx(Qt,{ref:g,variant:"outline-secondary",size:"sm",onClick:T,"aria-label":"Copy to clipboard",children:N()}),v.jsx(Jy,{show:c,target:(t==null?void 0:t.current)||g.current,placement:i,children:v.jsx(Um,{id:"copy-popover",children:v.jsx(Um.Body,{children:d==="success"?v.jsxs("span",{className:"text-success-emphasis",children:[v.jsx(Km,{})," ",A()]}):v.jsxs("span",{className:"text-danger-emphasis",children:[v.jsx(Jm,{})," ",A()]})})})})]})},jz=Cr(`
|
|
179
|
+
`),Tz={name:"moneypot.dev",baseUrl:"https://moneypot.dev",graphqlUrl:"https://api.moneypot.dev/graphql",apiKey:""},wz=wo().shape({name:ld().required(),baseUrl:E1().required(),graphqlUrl:b1().required(),apiKey:_z().required()}),Az=zt(({show:e,onHide:t})=>{const r=sn(),[i]=Hx(r,{document:Oz}),u=id({initialValues:Tz,validationSchema:wz,onSubmit:async(c,{setSubmitting:h,setStatus:d})=>(d(null),h(!0),i({variables:{input:{name:c.name,baseUrl:c.baseUrl,graphqlUrl:c.graphqlUrl,apiKey:c.apiKey}}}).then(m=>{var E;((E=m.hubAddCasino)==null?void 0:E.casino)&&(r.refetchCasinos(),t())}).catch(m=>{d(Bn(m))}).finally(()=>{h(!1)}))});return v.jsx(It,{show:e,onHide:t,size:"lg",children:v.jsxs(Ve,{onSubmit:u.handleSubmit,children:[v.jsx(It.Header,{closeButton:!0,children:v.jsx(It.Title,{children:"Add Casino"})}),v.jsxs(It.Body,{children:[u.status&&v.jsx(ur,{variant:"danger",className:"mb-3",children:u.status}),v.jsxs("fieldset",{disabled:u.isSubmitting,children:[v.jsxs(Ve.Group,{children:[v.jsx(Ve.Label,{children:"Name (for your own reference)"}),v.jsx(Ve.Control,{type:"text",name:"name",placeholder:"Ex: moneypot.dev",value:u.values.name,onChange:u.handleChange,onBlur:u.handleBlur,isInvalid:u.touched.name&&!!u.errors.name}),v.jsx(Ve.Control.Feedback,{type:"invalid",children:u.errors.name})]}),v.jsxs(Ve.Group,{className:"mt-2",children:[v.jsx(Ve.Label,{children:"Website base URL"}),v.jsx(Ve.Control,{type:"text",name:"baseUrl",placeholder:"Ex: https://moneypot.dev",value:u.values.baseUrl,onChange:u.handleChange,onBlur:u.handleBlur,isInvalid:u.touched.baseUrl&&!!u.errors.baseUrl}),v.jsx(Ve.Control.Feedback,{type:"invalid",children:u.errors.baseUrl})]}),v.jsxs(Ve.Group,{className:"mt-2",children:[v.jsx(Ve.Label,{children:"GraphQL URL"}),v.jsx(Ve.Control,{type:"text",name:"graphqlUrl",placeholder:"Ex: https://api.moneypot.dev/graphql",value:u.values.graphqlUrl,onChange:u.handleChange,onBlur:u.handleBlur,isInvalid:u.touched.graphqlUrl&&!!u.errors.graphqlUrl}),v.jsx(Ve.Control.Feedback,{type:"invalid",children:u.errors.graphqlUrl})]}),v.jsxs(Ve.Group,{className:"mt-2",children:[v.jsxs(Ve.Label,{children:["Controller API Key"," ",v.jsx(xz,{text:"This should be a valid api key that you created for your controller on the casino website"})]}),v.jsx(Ve.Control,{type:"text",name:"apiKey",placeholder:"Ex: 01234567-89ab-cdef-0123-456789abcdef",value:u.values.apiKey,onChange:u.handleChange,onBlur:u.handleBlur,isInvalid:u.touched.apiKey&&!!u.errors.apiKey}),v.jsx(Ve.Control.Feedback,{type:"invalid",children:u.errors.apiKey})]})]})]}),v.jsx(It.Footer,{children:v.jsx(Qt,{type:"submit",disabled:u.isSubmitting,children:u.isSubmitting?"Testing...":"Test connection and save"})})]})})}),Nz=zt(()=>{var i;const e=sn(),[t,r]=b.useState(!1);return v.jsxs("div",{children:[v.jsx(Az,{show:t,onHide:()=>r(!1)}),v.jsxs("h2",{children:["Casinos",v.jsx(Qt,{className:"float-end",onClick:()=>r(!0),children:"Add casino"})]}),v.jsxs(_i,{striped:!0,bordered:!0,hover:!0,children:[v.jsx("thead",{children:v.jsxs("tr",{children:[v.jsx("th",{children:"ID"}),v.jsx("th",{children:"Name"}),v.jsx("th",{children:"Base URL"}),v.jsx("th",{children:"GraphQL URL"}),v.jsx("th",{children:"Added"})]})}),v.jsx("tbody",{children:(i=e.loggedIn)==null?void 0:i.casinos.map(l=>v.jsxs("tr",{children:[v.jsx("td",{children:v.jsx($n,{to:`/casinos/${l.id}`,children:l.id})}),v.jsx("td",{children:l.name}),v.jsxs("td",{style:{whiteSpace:"nowrap"},children:[v.jsx("span",{className:"user-select-all",children:l.baseUrl})," ",v.jsx("a",{href:l.baseUrl,target:"_blank",rel:"noreferrer",className:"text-decoration-none",children:v.jsx(Gm,{style:{verticalAlign:"baseline"}})})]}),v.jsxs("td",{style:{whiteSpace:"nowrap"},children:[v.jsx("span",{className:"user-select-all",children:l.graphqlUrl})," ",v.jsx("a",{href:l.graphqlUrl,target:"_blank",rel:"noreferrer",className:"text-decoration-none",children:v.jsx(Gm,{style:{verticalAlign:"baseline"}})})]}),v.jsx("td",{children:v.jsx(Da,{date:El(l.id),variant:"long"})})]},l.id))})]})]})});function Oi(){var i,l;const{casinoId:e}=j_(),t=sn();return b.useEffect(()=>{var u;e&&!((u=t.loggedIn)!=null&&u.casinos.find(c=>c.id===e))&&console.warn(`Casino ${e} not found`)},[e,(i=t.loggedIn)==null?void 0:i.casinos]),((l=t.loggedIn)==null?void 0:l.casinos.find(u=>u.id===e))||null}const v_=[{path:"",title:"Casino"},{path:"users",title:"Users"},{path:"experiences",title:"Experiences"},{path:"bankrolls",title:"Bankrolls"},{path:"currencies",title:"Currencies"},{path:"deposits",title:"Deposits"},{path:"withdrawals",title:"Withdrawals"},{path:"jwks",title:"Pubkeys"}];function Cz(e,t){return e.sort((r,i)=>i.length-r.length).find(r=>t.includes("/"+r))}const Rz=zt(()=>{var h;const e=ka(),t=sn(),r=Mf(),i=Oi();if(!t.loggedIn)return v.jsx("div",{children:"You must be logged in"});if(!i)return v.jsx(Yr,{});const l=Cz(v_.map(d=>d.path),e.pathname),u=e.pathname.match(/^\/casinos\/[^/]+/),c=d=>{var E;if(!u)return;const m=d.target.value,y=(E=t.loggedIn)==null?void 0:E.casinos.find(g=>g.id===m);y&&r(e.pathname.replace(/\/casinos\/[^/]+/,`/casinos/${y.id}`))};return v.jsxs("div",{children:[v.jsxs(bT,{direction:"horizontal",style:{alignItems:"baseline"},children:[v.jsxs(Ip,{children:[v.jsx(Ip.Item,{linkAs:$n,linkProps:{to:"/casinos"},children:"Casinos"}),v.jsx(Ip.Item,{active:!0,children:i.name})]}),v.jsxs(Ve.Select,{className:"ms-2 d-inline-block",style:{width:"auto"},size:"sm",value:i.id,onChange:c,children:[v.jsx("option",{disabled:!0,children:"Select casino"}),(h=t.loggedIn)==null?void 0:h.casinos.map(d=>v.jsx("option",{value:d.id,children:d.name},d.id))]})]}),v.jsx("ul",{className:"nav nav-tabs mb-4 ",children:v_.map(d=>v.jsx("li",{className:"nav-item",children:v.jsx($n,{to:d.path,className:`nav-link ${l===d.path?"active":""}`,children:d.title})},d.path))}),v.jsx(M_,{})]})}),vi=({text:e,sourceRef:t,popoverDuration:r=1e3,popoverPlacement:i="top"})=>{const[l,u]=b.useState("idle"),[c,h]=b.useState(!1),[d,m]=b.useState("success"),y=b.useRef(null),E=b.useRef(null),g=b.useRef(null);b.useEffect(()=>()=>{y.current&&clearTimeout(y.current),E.current&&clearTimeout(E.current)},[]);const _=x=>{m(x),h(!0),E.current&&clearTimeout(E.current),E.current=setTimeout(()=>{h(!1)},r)},T=()=>{y.current&&clearTimeout(y.current),navigator.clipboard.writeText(e).then(()=>{u("success"),y.current=setTimeout(()=>u("idle"),r),_("success")}).catch(x=>{console.error("Failed to copy text: ",x),u("error"),y.current=setTimeout(()=>u("idle"),r),_("error")})},N=()=>{switch(l){case"success":return v.jsx(Km,{className:"text-success-emphasis"});case"error":return v.jsx(Jm,{className:"text-danger-emphasis"});default:return v.jsx(u1,{})}},A=()=>d==="success"?"Copied!":"Error";return v.jsxs(v.Fragment,{children:[v.jsx(Qt,{ref:g,variant:"outline-secondary",size:"sm",onClick:T,"aria-label":"Copy to clipboard",children:N()}),v.jsx(Jy,{show:c,target:(t==null?void 0:t.current)||g.current,placement:i,children:v.jsx(Um,{id:"copy-popover",children:v.jsx(Um.Body,{children:d==="success"?v.jsxs("span",{className:"text-success-emphasis",children:[v.jsx(Km,{})," ",A()]}):v.jsxs("span",{className:"text-danger-emphasis",children:[v.jsx(Jm,{})," ",A()]})})})})]})},jz=Cr(`
|
|
180
180
|
query ListCasinoUsers($casinoId: UUID!, $after: Cursor) {
|
|
181
181
|
hubCasinoById(id: $casinoId) {
|
|
182
182
|
id
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Dashboard</title>
|
|
7
|
-
<script type="module" crossorigin src="/dashboard/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/dashboard/assets/index-Tqyvm1Se.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="/dashboard/assets/index-tK7EUtyc.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
@@ -69,11 +69,8 @@ export const HubAddCasinoPlugin = makeExtendSchemaPlugin((build) => {
|
|
|
69
69
|
}
|
|
70
70
|
throw e;
|
|
71
71
|
});
|
|
72
|
-
if (!result) {
|
|
73
|
-
throw new GraphQLError("Invalid API key");
|
|
74
|
-
}
|
|
75
|
-
if (!result.currentController) {
|
|
76
|
-
throw new GraphQLError("Invalid API key");
|
|
72
|
+
if (!result || !result.currentController) {
|
|
73
|
+
throw new GraphQLError("Invalid API key for your casino controller. Go to your controller on the casino website and double check.");
|
|
77
74
|
}
|
|
78
75
|
let casino;
|
|
79
76
|
try {
|
|
@@ -127,6 +124,14 @@ export const HubAddCasinoPlugin = makeExtendSchemaPlugin((build) => {
|
|
|
127
124
|
SELECT casino_id, key
|
|
128
125
|
FROM hub.currency
|
|
129
126
|
WHERE casino_id = $1
|
|
127
|
+
`,
|
|
128
|
+
values: [casino.id],
|
|
129
|
+
});
|
|
130
|
+
await pgClient.query({
|
|
131
|
+
text: `
|
|
132
|
+
UPDATE hub.bankroll
|
|
133
|
+
SET amount = 1000000
|
|
134
|
+
WHERE casino_id = $1 AND currency_key = 'HOUSE'
|
|
130
135
|
`,
|
|
131
136
|
values: [casino.id],
|
|
132
137
|
});
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@moneypot/hub",
|
|
3
3
|
"author": "",
|
|
4
4
|
"keywords": [],
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.2",
|
|
6
6
|
"description": "",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "dist/src/index.js",
|
|
@@ -65,5 +65,5 @@
|
|
|
65
65
|
"typescript": "^5.4.5",
|
|
66
66
|
"typescript-eslint": "^8.0.1"
|
|
67
67
|
},
|
|
68
|
-
"license": ""
|
|
68
|
+
"license": "UNLICENSED"
|
|
69
69
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CaasAddCasinoPlugin: GraphileConfig.Plugin;
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { constant, context, object, sideEffect } from "postgraphile/grafast";
|
|
2
|
-
import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
|
|
3
|
-
import { exactlyOneRow } from "../db/util.js";
|
|
4
|
-
import { gql as generatedGql } from "../__generated__/gql.js";
|
|
5
|
-
import { GraphQLClient } from "graphql-request";
|
|
6
|
-
import { GraphQLError } from "graphql";
|
|
7
|
-
import { superuserPool, upsertCurrencies, withPgPoolTransaction, } from "../db/index.js";
|
|
8
|
-
import { logger } from "../logger.js";
|
|
9
|
-
import { assert, is } from "tsafe";
|
|
10
|
-
import * as jwtService from "../services/jwt-service.js";
|
|
11
|
-
import { startTransferProcessor } from "../process-transfers.js";
|
|
12
|
-
const GET_CURRENT_CONTROLLER = generatedGql(`
|
|
13
|
-
query GetCurrentController {
|
|
14
|
-
currentController {
|
|
15
|
-
id
|
|
16
|
-
}
|
|
17
|
-
allCurrencies {
|
|
18
|
-
nodes {
|
|
19
|
-
id
|
|
20
|
-
displayUnitName
|
|
21
|
-
displayUnitScale
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
`);
|
|
26
|
-
export const CaasAddCasinoPlugin = makeExtendSchemaPlugin((build) => {
|
|
27
|
-
const casinoTable = build.input.pgRegistry.pgResources.caas_casino;
|
|
28
|
-
return {
|
|
29
|
-
typeDefs: gql `
|
|
30
|
-
input CaasAddCasinoInput {
|
|
31
|
-
name: String!
|
|
32
|
-
baseUrl: String!
|
|
33
|
-
graphqlUrl: String!
|
|
34
|
-
apiKey: String!
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
type CaasAddCasinoPayload {
|
|
38
|
-
casino: CaasCasino
|
|
39
|
-
query: Query
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
extend type Mutation {
|
|
43
|
-
caasAddCasino(input: CaasAddCasinoInput!): CaasAddCasinoPayload
|
|
44
|
-
}
|
|
45
|
-
`,
|
|
46
|
-
plans: {
|
|
47
|
-
Mutation: {
|
|
48
|
-
caasAddCasino(_, { $input }) {
|
|
49
|
-
const $identity = context().get("identity");
|
|
50
|
-
const $casinoId = sideEffect([$input, $identity], ([input, identity]) => {
|
|
51
|
-
return withPgPoolTransaction(superuserPool, async (pgClient) => {
|
|
52
|
-
if (identity?.kind !== "operator") {
|
|
53
|
-
throw new GraphQLError("Unauthorized");
|
|
54
|
-
}
|
|
55
|
-
assert(is(input));
|
|
56
|
-
const { name, baseUrl, graphqlUrl, apiKey } = input;
|
|
57
|
-
const graphqlClient = new GraphQLClient(graphqlUrl, {
|
|
58
|
-
headers: {
|
|
59
|
-
Authorization: `apikey:${apiKey}`,
|
|
60
|
-
},
|
|
61
|
-
});
|
|
62
|
-
console.log(`[caasAddCasino] Making request to ${graphqlUrl}`);
|
|
63
|
-
const result = await graphqlClient
|
|
64
|
-
.request(GET_CURRENT_CONTROLLER)
|
|
65
|
-
.catch((e) => {
|
|
66
|
-
if (e.cause?.code === "ECONNREFUSED" ||
|
|
67
|
-
e.cause?.code === "ENOTFOUND") {
|
|
68
|
-
throw new GraphQLError(`Cannot connect to graphqlUrl`);
|
|
69
|
-
}
|
|
70
|
-
throw e;
|
|
71
|
-
});
|
|
72
|
-
if (!result) {
|
|
73
|
-
throw new GraphQLError("Invalid API key");
|
|
74
|
-
}
|
|
75
|
-
if (!result.currentController) {
|
|
76
|
-
throw new GraphQLError("Invalid API key");
|
|
77
|
-
}
|
|
78
|
-
let casino;
|
|
79
|
-
try {
|
|
80
|
-
casino = await pgClient
|
|
81
|
-
.query({
|
|
82
|
-
text: `
|
|
83
|
-
INSERT INTO caas.casino(name, base_url, graphql_url)
|
|
84
|
-
VALUES($1, $2, $3)
|
|
85
|
-
returning id
|
|
86
|
-
`,
|
|
87
|
-
values: [name, baseUrl, graphqlUrl],
|
|
88
|
-
})
|
|
89
|
-
.then((res) => {
|
|
90
|
-
console.log("res", res.rows);
|
|
91
|
-
return res;
|
|
92
|
-
})
|
|
93
|
-
.then(exactlyOneRow);
|
|
94
|
-
}
|
|
95
|
-
catch (e) {
|
|
96
|
-
if (e instanceof Error &&
|
|
97
|
-
"code" in e &&
|
|
98
|
-
e.code === "23505" &&
|
|
99
|
-
"constraint" in e) {
|
|
100
|
-
switch (e.constraint) {
|
|
101
|
-
case "casino_graphql_url_idx":
|
|
102
|
-
throw new GraphQLError("Casino with that graphqlUrl already exists");
|
|
103
|
-
case "casino_base_url_idx":
|
|
104
|
-
throw new GraphQLError("Casino with that baseUrl already exists");
|
|
105
|
-
default:
|
|
106
|
-
throw new GraphQLError(`Duplicate constraint violation: ${e.constraint}`);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
logger.error("Error adding casino", e);
|
|
110
|
-
throw e;
|
|
111
|
-
}
|
|
112
|
-
await pgClient.query({
|
|
113
|
-
text: `
|
|
114
|
-
INSERT INTO caas.casino_secret(id, controller_id, api_key)
|
|
115
|
-
VALUES($1, $2, $3)
|
|
116
|
-
`,
|
|
117
|
-
values: [casino.id, result.currentController.id, apiKey],
|
|
118
|
-
});
|
|
119
|
-
const currencies = result.allCurrencies?.nodes.flatMap((x) => x || []) || [];
|
|
120
|
-
await upsertCurrencies(pgClient, {
|
|
121
|
-
casinoId: casino.id,
|
|
122
|
-
currencies,
|
|
123
|
-
});
|
|
124
|
-
await pgClient.query({
|
|
125
|
-
text: `
|
|
126
|
-
INSERT INTO caas.bankroll (casino_id, currency_key)
|
|
127
|
-
SELECT casino_id, key
|
|
128
|
-
FROM caas.currency
|
|
129
|
-
WHERE casino_id = $1
|
|
130
|
-
`,
|
|
131
|
-
values: [casino.id],
|
|
132
|
-
});
|
|
133
|
-
logger.info(`Fetching JWKS for new casino from ${graphqlUrl}...`);
|
|
134
|
-
await jwtService.refreshCasinoJwksTask(pgClient, {
|
|
135
|
-
graphqlClient,
|
|
136
|
-
casinoId: casino.id,
|
|
137
|
-
});
|
|
138
|
-
startTransferProcessor({ casinoId: casino.id });
|
|
139
|
-
return casino.id;
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
return object({
|
|
143
|
-
casino: casinoTable.get({ id: $casinoId }),
|
|
144
|
-
query: constant(true),
|
|
145
|
-
});
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
|
-
};
|
|
150
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CaasAuthenticatePlugin: GraphileConfig.Plugin;
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import { GraphQLError } from "graphql";
|
|
2
|
-
import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
|
|
3
|
-
import { assert, is } from "tsafe";
|
|
4
|
-
import { GET_USER_FROM_USER_TOKEN } from "../graphql-queries.js";
|
|
5
|
-
import { exactlyOneRow, maybeOneRow } from "../db/util.js";
|
|
6
|
-
import { createGraphqlClient } from "../graphql-client.js";
|
|
7
|
-
import { constant, context, error, object, sideEffect, } from "postgraphile/grafast";
|
|
8
|
-
import { superuserPool, withPgPoolTransaction, } from "../db/index.js";
|
|
9
|
-
import { logger } from "../logger.js";
|
|
10
|
-
import * as jwtService from "../services/jwt-service.js";
|
|
11
|
-
import { extractGraphQLErrorInfo, isGraphQLError } from "../GraphQLError.js";
|
|
12
|
-
export const CaasAuthenticatePlugin = makeExtendSchemaPlugin(() => {
|
|
13
|
-
return {
|
|
14
|
-
typeDefs: gql `
|
|
15
|
-
input CaasAuthenticateInput {
|
|
16
|
-
casinoBaseUrl: String!
|
|
17
|
-
userToken: String!
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
type CaasAuthenticateSuccess {
|
|
21
|
-
experienceId: UUID!
|
|
22
|
-
sessionKey: UUID!
|
|
23
|
-
userId: UUID!
|
|
24
|
-
uname: String!
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
type CaasAuthenticatePayload {
|
|
28
|
-
query: Query
|
|
29
|
-
success: CaasAuthenticateSuccess
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
extend type Mutation {
|
|
33
|
-
caasAuthenticate(input: CaasAuthenticateInput!): CaasAuthenticatePayload
|
|
34
|
-
}
|
|
35
|
-
`,
|
|
36
|
-
plans: {
|
|
37
|
-
Mutation: {
|
|
38
|
-
caasAuthenticate(_, { $input }) {
|
|
39
|
-
try {
|
|
40
|
-
const $context = context();
|
|
41
|
-
const $success = sideEffect([$input, $context], ([input, context]) => {
|
|
42
|
-
return withPgPoolTransaction(superuserPool, async (pgClient) => {
|
|
43
|
-
assert(is(input));
|
|
44
|
-
const { userToken: jwt, casinoBaseUrl } = input;
|
|
45
|
-
const casino = await pgClient
|
|
46
|
-
.query({
|
|
47
|
-
text: `
|
|
48
|
-
SELECT c.*, s.api_key
|
|
49
|
-
FROM caas.casino c
|
|
50
|
-
LEFT JOIN caas.casino_secret s ON c.id = s.id
|
|
51
|
-
WHERE c.base_url = $1`,
|
|
52
|
-
values: [casinoBaseUrl],
|
|
53
|
-
})
|
|
54
|
-
.then(maybeOneRow);
|
|
55
|
-
if (!casino) {
|
|
56
|
-
throw new GraphQLError(`CAAS is unaware of casino with a base url of provided casinoBaseUrl`);
|
|
57
|
-
}
|
|
58
|
-
if (!casino.api_key) {
|
|
59
|
-
throw new GraphQLError("Casino secret not configured");
|
|
60
|
-
}
|
|
61
|
-
const graphqlClient = createGraphqlClient({
|
|
62
|
-
graphqlUrl: casino.graphql_url,
|
|
63
|
-
apiKey: casino.api_key,
|
|
64
|
-
});
|
|
65
|
-
const verifyResult = await jwtService.verifyJwtFromDbCacheAndEnsureNotAlreadyUsed(pgClient, {
|
|
66
|
-
casinoId: casino.id,
|
|
67
|
-
jwt,
|
|
68
|
-
});
|
|
69
|
-
if (!verifyResult.ok) {
|
|
70
|
-
throw new GraphQLError(`Error verifying userToken: ${verifyResult.error}`);
|
|
71
|
-
}
|
|
72
|
-
const { userToken } = verifyResult.value;
|
|
73
|
-
let res;
|
|
74
|
-
try {
|
|
75
|
-
res = await graphqlClient.request(GET_USER_FROM_USER_TOKEN, {
|
|
76
|
-
token: userToken,
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
catch (e) {
|
|
80
|
-
logger.error(`[caasAuthenticate] Error when making GET_USER_FROM_USER_TOKEN to casino:`, e);
|
|
81
|
-
if (isGraphQLError(e)) {
|
|
82
|
-
const errorInfo = extractGraphQLErrorInfo(e);
|
|
83
|
-
if (errorInfo.code === "UNAUTHENTICATED") {
|
|
84
|
-
throw new GraphQLError("Invalid api key");
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
throw new GraphQLError(errorInfo.message);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
throw error;
|
|
91
|
-
}
|
|
92
|
-
const result = res.userFromUserToken;
|
|
93
|
-
if (!result || !result.user || !result.experience) {
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
const mpUserId = result.user.id;
|
|
97
|
-
assert(mpUserId);
|
|
98
|
-
const uname = result.user.uname;
|
|
99
|
-
assert(uname);
|
|
100
|
-
const dbUser = await pgClient
|
|
101
|
-
.query({
|
|
102
|
-
text: `
|
|
103
|
-
INSERT INTO caas.user(casino_id, mp_user_id, uname)
|
|
104
|
-
VALUES($1, $2, $3)
|
|
105
|
-
ON CONFLICT (casino_id, mp_user_id) DO UPDATE
|
|
106
|
-
SET uname = EXCLUDED.uname
|
|
107
|
-
RETURNING id, uname
|
|
108
|
-
`,
|
|
109
|
-
values: [casino.id, mpUserId, uname],
|
|
110
|
-
})
|
|
111
|
-
.then(exactlyOneRow);
|
|
112
|
-
const userId = dbUser.id;
|
|
113
|
-
const mpExperience = result.experience;
|
|
114
|
-
assert(mpExperience);
|
|
115
|
-
const dbExperience = await pgClient
|
|
116
|
-
.query({
|
|
117
|
-
text: `
|
|
118
|
-
INSERT INTO caas.experience(casino_id, mp_experience_id, name)
|
|
119
|
-
VALUES($1, $2, $3)
|
|
120
|
-
ON CONFLICT (casino_id, mp_experience_id) DO UPDATE
|
|
121
|
-
SET name = EXCLUDED.name
|
|
122
|
-
RETURNING id
|
|
123
|
-
`,
|
|
124
|
-
values: [casino.id, mpExperience.id, mpExperience.name],
|
|
125
|
-
})
|
|
126
|
-
.then(exactlyOneRow);
|
|
127
|
-
const dbSession = await pgClient
|
|
128
|
-
.query({
|
|
129
|
-
text: `
|
|
130
|
-
INSERT INTO caas.session(casino_id, user_id, experience_id, user_token)
|
|
131
|
-
VALUES($1, $2, $3, $4)
|
|
132
|
-
RETURNING id, key
|
|
133
|
-
`,
|
|
134
|
-
values: [casino.id, userId, dbExperience.id, userToken],
|
|
135
|
-
})
|
|
136
|
-
.then(exactlyOneRow);
|
|
137
|
-
const ret = {
|
|
138
|
-
userId,
|
|
139
|
-
uname: dbUser.uname,
|
|
140
|
-
experienceId: dbExperience.id,
|
|
141
|
-
sessionKey: dbSession.key,
|
|
142
|
-
};
|
|
143
|
-
context.identity = {
|
|
144
|
-
kind: "user",
|
|
145
|
-
session: {
|
|
146
|
-
user_id: userId,
|
|
147
|
-
mp_user_id: mpUserId,
|
|
148
|
-
casino_id: casino.id,
|
|
149
|
-
experience_id: dbExperience.id,
|
|
150
|
-
session_id: dbSession.id,
|
|
151
|
-
},
|
|
152
|
-
};
|
|
153
|
-
context.pgSettings = {
|
|
154
|
-
"session.user_id": userId,
|
|
155
|
-
"session.casino_id": casino.id,
|
|
156
|
-
"session.experience_id": dbExperience.id,
|
|
157
|
-
"session.session_id": dbSession.id,
|
|
158
|
-
};
|
|
159
|
-
return ret;
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
return object({
|
|
163
|
-
query: constant(true),
|
|
164
|
-
success: $success,
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
catch (error) {
|
|
168
|
-
logger.error(error);
|
|
169
|
-
throw error;
|
|
170
|
-
}
|
|
171
|
-
},
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
};
|
|
175
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CaasBalanceAlertPlugin: GraphileConfig.Plugin;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { makeExtendSchemaPlugin, gql } from "postgraphile/utils";
|
|
2
|
-
import { context, lambda, listen } from "postgraphile/grafast";
|
|
3
|
-
import { jsonParse } from "postgraphile/@dataplan/json";
|
|
4
|
-
export const CaasBalanceAlertPlugin = makeExtendSchemaPlugin(() => {
|
|
5
|
-
return {
|
|
6
|
-
typeDefs: gql `
|
|
7
|
-
extend type Subscription {
|
|
8
|
-
caasBalanceAlert: CaasBalanceAlertPayload
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
type CaasBalanceAlertPayload {
|
|
12
|
-
currencyKey: String
|
|
13
|
-
}
|
|
14
|
-
`,
|
|
15
|
-
plans: {
|
|
16
|
-
Subscription: {
|
|
17
|
-
caasBalanceAlert: {
|
|
18
|
-
subscribePlan(_$root) {
|
|
19
|
-
const $pgSubscriber = context().get("pgSubscriber");
|
|
20
|
-
const $identity = context().get("identity");
|
|
21
|
-
const $channelKey = lambda($identity, (identity) => {
|
|
22
|
-
if (identity?.kind === "user") {
|
|
23
|
-
return `caas:user:${identity.session.user_id}:balance_alert`;
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
return "";
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
return listen($pgSubscriber, $channelKey, jsonParse);
|
|
30
|
-
},
|
|
31
|
-
plan($event) {
|
|
32
|
-
return $event;
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
CaasBalanceAlertPayload: {
|
|
37
|
-
currencyKey($event) {
|
|
38
|
-
return $event.get("currency_key");
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
};
|
|
43
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CaasClaimFaucetPlugin: GraphileConfig.Plugin;
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { object } from "grafast";
|
|
2
|
-
import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
|
|
3
|
-
import { superuserPool, withPgPoolTransaction } from "../db/index.js";
|
|
4
|
-
import { constant, context, sideEffect } from "postgraphile/grafast";
|
|
5
|
-
const CLAIM_AMOUNT = 1000;
|
|
6
|
-
export const CaasClaimFaucetPlugin = makeExtendSchemaPlugin(() => {
|
|
7
|
-
return {
|
|
8
|
-
typeDefs: gql `
|
|
9
|
-
type CaasClaimFaucetPayload {
|
|
10
|
-
success: Boolean!
|
|
11
|
-
query: Query
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
extend type Mutation {
|
|
15
|
-
caasClaimFaucet: CaasClaimFaucetPayload
|
|
16
|
-
}
|
|
17
|
-
`,
|
|
18
|
-
plans: {
|
|
19
|
-
Mutation: {
|
|
20
|
-
caasClaimFaucet() {
|
|
21
|
-
const $identity = context().get("identity");
|
|
22
|
-
const $result = sideEffect([$identity], ([identity]) => {
|
|
23
|
-
if (identity?.kind !== "user") {
|
|
24
|
-
throw new Error("Must be logged in as user");
|
|
25
|
-
}
|
|
26
|
-
const { session } = identity;
|
|
27
|
-
return withPgPoolTransaction(superuserPool, async (pgClient) => {
|
|
28
|
-
await upsertPlayCurrency(pgClient, session.casino_id);
|
|
29
|
-
await pgClient.query({
|
|
30
|
-
text: `
|
|
31
|
-
insert into caas.faucet_claim (user_id, casino_id, experience_id, currency_key, amount)
|
|
32
|
-
values ($1, $2, $3, $4, $5)
|
|
33
|
-
`,
|
|
34
|
-
values: [
|
|
35
|
-
session.user_id,
|
|
36
|
-
session.casino_id,
|
|
37
|
-
session.experience_id,
|
|
38
|
-
"PLAY",
|
|
39
|
-
CLAIM_AMOUNT,
|
|
40
|
-
],
|
|
41
|
-
});
|
|
42
|
-
await pgClient.query({
|
|
43
|
-
text: `
|
|
44
|
-
INSERT INTO caas.balance (user_id, experience_id, casino_id, currency_key, amount)
|
|
45
|
-
VALUES ($1, $2, $3, $4, $5)
|
|
46
|
-
ON CONFLICT (user_id, experience_id, casino_id, currency_key) DO UPDATE
|
|
47
|
-
SET amount = balance.amount + EXCLUDED.amount
|
|
48
|
-
`,
|
|
49
|
-
values: [
|
|
50
|
-
session.user_id,
|
|
51
|
-
session.experience_id,
|
|
52
|
-
session.casino_id,
|
|
53
|
-
"PLAY",
|
|
54
|
-
CLAIM_AMOUNT,
|
|
55
|
-
],
|
|
56
|
-
});
|
|
57
|
-
return true;
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
return object({
|
|
61
|
-
result: $result,
|
|
62
|
-
});
|
|
63
|
-
},
|
|
64
|
-
},
|
|
65
|
-
CaasClaimFaucetPayload: {
|
|
66
|
-
success($data) {
|
|
67
|
-
return $data.get("result");
|
|
68
|
-
},
|
|
69
|
-
query() {
|
|
70
|
-
return constant(true);
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
});
|
|
76
|
-
async function upsertPlayCurrency(pgClient, casinoId) {
|
|
77
|
-
return pgClient.query({
|
|
78
|
-
text: `
|
|
79
|
-
insert into caas.currency (casino_id, key, display_unit_name, display_unit_scale)
|
|
80
|
-
values ($1, 'PLAY', 'tokens', 1)
|
|
81
|
-
on conflict (casino_id, key) do nothing
|
|
82
|
-
`,
|
|
83
|
-
values: [casinoId],
|
|
84
|
-
});
|
|
85
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CaasCurrentXPlugin: GraphileConfig.Plugin;
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { gql, makeExtendSchemaPlugin } from "graphile-utils";
|
|
2
|
-
import { context, inhibitOnNull, lambda } from "postgraphile/grafast";
|
|
3
|
-
export const CaasCurrentXPlugin = makeExtendSchemaPlugin((build) => {
|
|
4
|
-
const userTable = build.input.pgRegistry.pgResources.caas_user;
|
|
5
|
-
const casinoTable = build.input.pgRegistry.pgResources.caas_casino;
|
|
6
|
-
const experienceTable = build.input.pgRegistry.pgResources.caas_experience;
|
|
7
|
-
const sessionTable = build.input.pgRegistry.pgResources.caas_session;
|
|
8
|
-
return {
|
|
9
|
-
typeDefs: gql `
|
|
10
|
-
extend type Query {
|
|
11
|
-
caasCurrentUser: CaasUser
|
|
12
|
-
caasCurrentCasino: CaasCasino
|
|
13
|
-
caasCurrentExperience: CaasExperience
|
|
14
|
-
caasCurrentSession: CaasSession
|
|
15
|
-
}
|
|
16
|
-
`,
|
|
17
|
-
plans: {
|
|
18
|
-
Query: {
|
|
19
|
-
caasCurrentUser() {
|
|
20
|
-
const $identity = context().get("identity");
|
|
21
|
-
const $userId = lambda($identity, (identity) => {
|
|
22
|
-
if (identity?.kind === "user") {
|
|
23
|
-
return identity.session.user_id;
|
|
24
|
-
}
|
|
25
|
-
return null;
|
|
26
|
-
});
|
|
27
|
-
return userTable.get({ id: inhibitOnNull($userId) });
|
|
28
|
-
},
|
|
29
|
-
caasCurrentCasino() {
|
|
30
|
-
const $identity = context().get("identity");
|
|
31
|
-
const $casinoId = lambda($identity, (identity) => {
|
|
32
|
-
if (identity?.kind === "user") {
|
|
33
|
-
return identity.session.casino_id;
|
|
34
|
-
}
|
|
35
|
-
return null;
|
|
36
|
-
});
|
|
37
|
-
return casinoTable.get({ id: inhibitOnNull($casinoId) });
|
|
38
|
-
},
|
|
39
|
-
caasCurrentExperience() {
|
|
40
|
-
const $identity = context().get("identity");
|
|
41
|
-
const $experienceId = lambda($identity, (identity) => {
|
|
42
|
-
if (identity?.kind === "user") {
|
|
43
|
-
return identity.session.experience_id;
|
|
44
|
-
}
|
|
45
|
-
return null;
|
|
46
|
-
});
|
|
47
|
-
return experienceTable.get({ id: inhibitOnNull($experienceId) });
|
|
48
|
-
},
|
|
49
|
-
caasCurrentSession() {
|
|
50
|
-
const $identity = context().get("identity");
|
|
51
|
-
const $sessionId = lambda($identity, (identity) => {
|
|
52
|
-
if (identity?.kind === "user") {
|
|
53
|
-
return identity.session.session_id;
|
|
54
|
-
}
|
|
55
|
-
return null;
|
|
56
|
-
});
|
|
57
|
-
return sessionTable.get({ id: inhibitOnNull($sessionId) });
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CaasPrefixPlugin: GraphileConfig.Plugin;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export const CaasPrefixPlugin = {
|
|
2
|
-
name: "CaasPrefixPlugin",
|
|
3
|
-
version: "1.0.0",
|
|
4
|
-
after: ["PgTablesPlugin"],
|
|
5
|
-
inflection: {
|
|
6
|
-
replace: {
|
|
7
|
-
_schemaPrefix(previous, options, { pgNamespace, serviceName, }) {
|
|
8
|
-
const pgService = options.pgServices?.find((db) => db.name === serviceName);
|
|
9
|
-
const databasePrefix = serviceName === "main" ? "" : `${serviceName}_`;
|
|
10
|
-
let schemaPrefix;
|
|
11
|
-
if (pgNamespace.nspname === "caas" ||
|
|
12
|
-
pgNamespace.nspname.startsWith("caas_")) {
|
|
13
|
-
schemaPrefix = `${pgNamespace.nspname}_`;
|
|
14
|
-
}
|
|
15
|
-
else if (pgNamespace.nspname === pgService?.schemas?.[0]) {
|
|
16
|
-
schemaPrefix = "";
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
schemaPrefix = `${pgNamespace.nspname}_`;
|
|
20
|
-
}
|
|
21
|
-
return `${databasePrefix}${schemaPrefix}`;
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CaasUserBalanceByCurrencyPlugin: GraphileConfig.Plugin;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { access, context, loadOne, object, } from "postgraphile/grafast";
|
|
2
|
-
import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
|
|
3
|
-
import { superuserPool } from "../db/index.js";
|
|
4
|
-
import { pgSelectSingleFromRecord, } from "postgraphile/@dataplan/pg";
|
|
5
|
-
export const CaasUserBalanceByCurrencyPlugin = makeExtendSchemaPlugin((build) => {
|
|
6
|
-
const balances = build.input.pgRegistry.pgResources.caas_balance;
|
|
7
|
-
return {
|
|
8
|
-
typeDefs: gql `
|
|
9
|
-
extend type CaasUser {
|
|
10
|
-
balanceByCurrency(currency: String!): CaasBalance
|
|
11
|
-
}
|
|
12
|
-
`,
|
|
13
|
-
plans: {
|
|
14
|
-
CaasUser: {
|
|
15
|
-
balanceByCurrency: ($record, { $currency }) => {
|
|
16
|
-
const $identity = context().get("identity");
|
|
17
|
-
const $params = object({
|
|
18
|
-
currency: $currency,
|
|
19
|
-
targetUserId: $record.get("id"),
|
|
20
|
-
casino_id: access($identity, ["session", "casino_id"]),
|
|
21
|
-
experience_id: access($identity, ["session", "experience_id"]),
|
|
22
|
-
});
|
|
23
|
-
const $balance = loadOne($params, batchGetUserBalanceByCurrency);
|
|
24
|
-
return pgSelectSingleFromRecord(balances, $balance);
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
});
|
|
30
|
-
async function batchGetUserBalanceByCurrency(paramsArray) {
|
|
31
|
-
const values = [];
|
|
32
|
-
const valuePlaceholders = [];
|
|
33
|
-
paramsArray.forEach((p, index) => {
|
|
34
|
-
const baseIndex = index * 4 + 1;
|
|
35
|
-
valuePlaceholders.push(`($${baseIndex}, $${baseIndex + 1}::uuid, $${baseIndex + 2}::uuid, $${baseIndex + 3}::uuid)`);
|
|
36
|
-
values.push(p.currency, p.targetUserId, p.casino_id, p.experience_id);
|
|
37
|
-
});
|
|
38
|
-
const sql = `
|
|
39
|
-
SELECT b.*
|
|
40
|
-
FROM caas.balance b
|
|
41
|
-
JOIN (
|
|
42
|
-
VALUES
|
|
43
|
-
${valuePlaceholders.join(",\n ")}
|
|
44
|
-
) AS vals(currency_key, user_id, casino_id, experience_id)
|
|
45
|
-
ON b.currency_key = vals.currency_key
|
|
46
|
-
AND b.user_id = vals.user_id
|
|
47
|
-
AND b.casino_id = vals.casino_id
|
|
48
|
-
AND b.experience_id = vals.experience_id
|
|
49
|
-
`;
|
|
50
|
-
const { rows } = await superuserPool.query(sql, values);
|
|
51
|
-
return paramsArray.map((p) => rows.find((row) => row.currency_key === p.currency &&
|
|
52
|
-
row.user_id === p.targetUserId &&
|
|
53
|
-
row.casino_id === p.casino_id &&
|
|
54
|
-
row.experience_id === p.experience_id));
|
|
55
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CaasWithdrawPlugin: GraphileConfig.Plugin;
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { constant, context, object, sideEffect } from "postgraphile/grafast";
|
|
2
|
-
import { gql, makeExtendSchemaPlugin } from "postgraphile/utils";
|
|
3
|
-
import { superuserPool, withPgPoolTransaction, } from "../db/index.js";
|
|
4
|
-
import { exactlyOneRow, maybeOneRow } from "../db/util.js";
|
|
5
|
-
import { GraphQLError } from "graphql";
|
|
6
|
-
export const CaasWithdrawPlugin = makeExtendSchemaPlugin((build) => {
|
|
7
|
-
const caasWithdrawalRequests = build.input.pgRegistry.pgResources.caas_withdrawal_request;
|
|
8
|
-
return {
|
|
9
|
-
typeDefs: gql `
|
|
10
|
-
input CaasWithdrawInput {
|
|
11
|
-
amount: Int!
|
|
12
|
-
currency: String!
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
type CaasWithdrawPayload {
|
|
16
|
-
withdrawalRequest: CaasWithdrawalRequest!
|
|
17
|
-
query: Query
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
extend type Mutation {
|
|
21
|
-
caasWithdraw(input: CaasWithdrawInput!): CaasWithdrawPayload
|
|
22
|
-
}
|
|
23
|
-
`,
|
|
24
|
-
plans: {
|
|
25
|
-
Mutation: {
|
|
26
|
-
caasWithdraw(_, { $input }) {
|
|
27
|
-
const $identity = context().get("identity");
|
|
28
|
-
const $withdrawalRequestId = sideEffect([$input, $identity], ([input, identity]) => {
|
|
29
|
-
if (identity?.kind !== "user") {
|
|
30
|
-
throw new GraphQLError("You must be logged in");
|
|
31
|
-
}
|
|
32
|
-
const { session } = identity;
|
|
33
|
-
return withPgPoolTransaction(superuserPool, async (pgClient) => {
|
|
34
|
-
const { amount, currency } = input;
|
|
35
|
-
if (amount <= 0) {
|
|
36
|
-
throw new GraphQLError("Withdraw amount must be greater than zero");
|
|
37
|
-
}
|
|
38
|
-
if (!Number.isInteger(amount)) {
|
|
39
|
-
throw new GraphQLError("Withdraw amount must be an integer");
|
|
40
|
-
}
|
|
41
|
-
const dbCurrency = await pgClient
|
|
42
|
-
.query({
|
|
43
|
-
text: `
|
|
44
|
-
SELECT key
|
|
45
|
-
FROM caas.currency
|
|
46
|
-
WHERE key = $1 AND casino_id = $2
|
|
47
|
-
`,
|
|
48
|
-
values: [currency, session.casino_id],
|
|
49
|
-
})
|
|
50
|
-
.then(maybeOneRow);
|
|
51
|
-
if (!dbCurrency) {
|
|
52
|
-
throw new GraphQLError("Currency not supported");
|
|
53
|
-
}
|
|
54
|
-
const balance = await pgClient
|
|
55
|
-
.query({
|
|
56
|
-
text: `
|
|
57
|
-
select *
|
|
58
|
-
from caas.balance
|
|
59
|
-
where currency_key = $1
|
|
60
|
-
and user_id = $2
|
|
61
|
-
and casino_id = $3
|
|
62
|
-
and experience_id = $4
|
|
63
|
-
|
|
64
|
-
FOR UPDATE
|
|
65
|
-
`,
|
|
66
|
-
values: [
|
|
67
|
-
currency,
|
|
68
|
-
session.user_id,
|
|
69
|
-
session.casino_id,
|
|
70
|
-
session.experience_id,
|
|
71
|
-
],
|
|
72
|
-
})
|
|
73
|
-
.then(maybeOneRow);
|
|
74
|
-
if (!balance || balance.amount < amount) {
|
|
75
|
-
throw new GraphQLError("Insufficient funds for withdrawal");
|
|
76
|
-
}
|
|
77
|
-
const dbWithdrawalRequest = await pgClient
|
|
78
|
-
.query({
|
|
79
|
-
text: `
|
|
80
|
-
insert into caas.withdrawal_request(
|
|
81
|
-
user_id,
|
|
82
|
-
experience_id,
|
|
83
|
-
casino_id,
|
|
84
|
-
amount,
|
|
85
|
-
currency_key
|
|
86
|
-
)
|
|
87
|
-
values ($1, $2, $3, $4, $5)
|
|
88
|
-
returning id
|
|
89
|
-
`,
|
|
90
|
-
values: [
|
|
91
|
-
session.user_id,
|
|
92
|
-
session.experience_id,
|
|
93
|
-
session.casino_id,
|
|
94
|
-
amount,
|
|
95
|
-
currency,
|
|
96
|
-
],
|
|
97
|
-
})
|
|
98
|
-
.then(exactlyOneRow);
|
|
99
|
-
await pgClient.query({
|
|
100
|
-
text: `
|
|
101
|
-
update caas.balance
|
|
102
|
-
set amount = amount - $1
|
|
103
|
-
where user_id = $2
|
|
104
|
-
and experience_id = $3
|
|
105
|
-
and currency_key = $4
|
|
106
|
-
and casino_id = $5
|
|
107
|
-
`,
|
|
108
|
-
values: [
|
|
109
|
-
amount,
|
|
110
|
-
session.user_id,
|
|
111
|
-
session.experience_id,
|
|
112
|
-
currency,
|
|
113
|
-
session.casino_id,
|
|
114
|
-
],
|
|
115
|
-
});
|
|
116
|
-
return dbWithdrawalRequest.id;
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
return object({
|
|
120
|
-
withdrawalRequestId: $withdrawalRequestId,
|
|
121
|
-
query: constant(true),
|
|
122
|
-
});
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
CaasWithdrawPayload: {
|
|
126
|
-
withdrawalRequest($data) {
|
|
127
|
-
const $id = $data.get("withdrawalRequestId");
|
|
128
|
-
return caasWithdrawalRequests.get({ id: $id });
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
};
|
|
133
|
-
});
|