diff --git a/package.json b/package.json index 0211098..d5004b4 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "author": "@circle-fin", "license": "ISC", "dependencies": { - "@circle-fin/user-controlled-wallets": "^3.0.0", + "@circle-fin/user-controlled-wallets": "^4.0.0", "bcrypt": "^5.1.1", "cors": "^2.8.5", "dotenv": "^16.4.1", diff --git a/src/app.ts b/src/app.ts index 261c7b4..3f263bc 100644 --- a/src/app.ts +++ b/src/app.ts @@ -30,7 +30,8 @@ import { tokens as tokensRouter, wallets as walletsRouter, transactions as transactionsRouter, - authTransRouter + authTransRouter, + faucet as faucetRouter } from './routers'; export const app: Express = express(); @@ -91,6 +92,7 @@ app.use('/users', usersRouter, authUserRouter); app.use('/tokens', tokensRouter); app.use('/wallets', authMiddleware, walletsRouter); app.use('/transactions', transactionsRouter, authTransRouter); +app.use('/faucet', authMiddleware, faucetRouter); // Error handling app.use(errorHandler); diff --git a/src/controllers/faucet.ts b/src/controllers/faucet.ts new file mode 100644 index 0000000..10e9705 --- /dev/null +++ b/src/controllers/faucet.ts @@ -0,0 +1,36 @@ +// Copyright (c) 2024, Circle Technologies, LLC. All rights reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { NextFunction, Request, Response } from 'express'; +import { circleUserSdk } from '../services'; + +export const dripFaucet = async ( + req: Request, + res: Response, + next: NextFunction +) => { + try { + await circleUserSdk.requestTestnetTokens({ + address: req.body.address, + blockchain: req.body.blockchain, + usdc: true + }); + + res.status(200).send(); + } catch (error: unknown) { + next(error); + } +}; diff --git a/src/controllers/index.ts b/src/controllers/index.ts index a1b5564..ba6fe35 100644 --- a/src/controllers/index.ts +++ b/src/controllers/index.ts @@ -19,3 +19,4 @@ export * from './onboarding'; export * from './wallets'; export * from './transactions'; export * from './tokens'; +export * from './faucet'; diff --git a/src/controllers/onboarding.ts b/src/controllers/onboarding.ts index a47abca..c9639bb 100644 --- a/src/controllers/onboarding.ts +++ b/src/controllers/onboarding.ts @@ -85,6 +85,7 @@ export const signInCallback = (req: Request, res: Response) => res.sendStatus(401); return; } + // valid credentials const tokenResponse = await circleUserSdk.createUserToken({ userId: user.userId diff --git a/src/middleware/types/schemas.ts b/src/middleware/types/schemas.ts index 77a6e37..c8a5c5f 100644 --- a/src/middleware/types/schemas.ts +++ b/src/middleware/types/schemas.ts @@ -198,3 +198,14 @@ export const getTokenDetailsSchema = yup.object({ .noUnknown(true) .strict() }); + +// Faucet +export const postFaucetDripSchema = yup.object({ + body: yup + .object({ + address: yup.string().required(), + blockchain: yup.string().required() + }) + .noUnknown(true) + .strict() +}); diff --git a/src/routers/faucet.ts b/src/routers/faucet.ts new file mode 100644 index 0000000..0c38912 --- /dev/null +++ b/src/routers/faucet.ts @@ -0,0 +1,36 @@ +// Copyright (c) 2024, Circle Technologies, LLC. All rights reserved. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import express from 'express'; +import { postFaucetDripSchema, validate } from '../middleware'; +import { dripFaucet } from '../controllers'; + +const faucet = express.Router(); + +/** + * POST - /faucet/drips + * Request testnet tokens to specified wallet. + * + * Params: + * address: string - Wallet address + * blockchain: string - Specified blockchain + * + * Returns: null + * + */ +faucet.post('/drips', validate(postFaucetDripSchema), dripFaucet); + +export { faucet }; diff --git a/src/routers/index.ts b/src/routers/index.ts index 47da20b..f073a98 100644 --- a/src/routers/index.ts +++ b/src/routers/index.ts @@ -18,3 +18,4 @@ export * from './transactions'; export * from './wallets'; export * from './tokens'; export * from './users'; +export * from './faucet'; diff --git a/yarn.lock b/yarn.lock index 9355e17..74b1b2f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -303,10 +303,10 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@circle-fin/user-controlled-wallets@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@circle-fin/user-controlled-wallets/-/user-controlled-wallets-3.0.0.tgz#be0fb94f127828ee17d854db742e8792b063cc7f" - integrity sha512-uO+64680yC3nWVweMDIc8o2gSmh1oYn/ydXy3rMT232auyY/jPNbu6Ff2Luqrn+QIPIn19TNqmgguCAhXCmi+g== +"@circle-fin/user-controlled-wallets@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@circle-fin/user-controlled-wallets/-/user-controlled-wallets-4.0.0.tgz#6b7fc3b27ba69fa8ffbdc20259aeb256b5589d09" + integrity sha512-n7RKX2+XaqNLzgv60TSaKLZrU/O4jUcwd+pL9tvcIbuo3zuyPT0pVjws2QA3RODu5Y847km4HcAlfX61mUINSA== dependencies: axios "^1.6.2"