aws-lambda#Context TypeScript Examples

The following examples show how to use aws-lambda#Context. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: alerts.ts    From ethgaswatch with MIT License 6 votes vote down vote up
export async function handler(event: APIGatewayEvent, context: Context) {
  context.callbackWaitsForEmptyEventLoop = false;

  const data = await GetUserAlertsData();
  
  return {
      statusCode: 200,
      body: JSON.stringify(data),
      headers: {
        'Cache-Control': 'public, max-age=1800',
      }
  }
}
Example #2
Source File: addCustomer.ts    From Stripe-shop-backend with MIT License 6 votes vote down vote up
addCustomer: Handler = async (event: APIGatewayEvent | ScheduledEvent, context: Context, callBack: Callback) => {

    const data: CustomerInput & saveCustomer =  JSON.parse((event as APIGatewayEvent).body);
    console.log('incomming data', data);
    const validCustomer: validCustomer = validateCustomer(data);

    if (! validCustomer.isValid) {
        return errorHandler(callBack, 'ERROR: Customer contains invalid data.', validCustomer.error );
    }

    try {

        const stripeCustomer = (data.isSaveCustomer === 1) && await upsertToStripe(validCustomer);
        validCustomer.params.StripeCustomerId = (data.isSaveCustomer) ? stripeCustomer.id : '';

        const params: CustomerTable = {
            TableName: process.env.DYNAMODB_TABLE_CUSTOMERS,
            Item: validCustomer.params,
        };
        const savedData = await upsert(params);
        console.log('savedData', savedData);

        return successHandler(
            callBack,
            {
                message: 'Stripe Customer Created!',
                id: params.Item.customerId,
                stripeCustomer: stripeCustomer,
            });
    }
    catch(error) {
        return errorHandler(
            callBack,
            'ERROR Customer Creation FAILED!',
            error
        );
    }
}
Example #3
Source File: handler.test.ts    From serverless-typescript-starter with MIT License 6 votes vote down vote up
test("hello", async () => {
  const event = { body: "Test Body" } as APIGatewayEvent;
  const context = {} as Context;

  const response = await handler.hello(event, context);

  expect(response.statusCode).toEqual(200);
  expect(typeof response.body).toBe("string");
});
Example #4
Source File: getOrder.ts    From Stripe-shop-backend with MIT License 6 votes vote down vote up
getOrder: Handler = (event: APIGatewayEvent | ScheduledEvent, context: Context, callBack: Callback) => {

    const data =  JSON.parse((event as APIGatewayEvent).body);
    const params = {
        TableName: process.env.DYNAMODB_TABLE_ORDERS,
        Key: {
            orderId: data.orderId,
        },
    };

    dynamoDb.get(params, (error, result) => {
        // handle potential errors
        if (error) {
            console.error(error);
            return errorHandler(callBack, 'ERROR: Couldn\'t fetch the order', error );
        }
        // create a response
        return successHandler(callBack, result);

    });
}
Example #5
Source File: payment-methods.ts    From sleekypay with MIT License 6 votes vote down vote up
exports.handler = async function (event: APIGatewayEvent, context: Context, callback: Callback) {
  // Get request's body
  const request = JSON.parse(event.body)
  const API_URL = process.env.API_URL || 'https://localhost:12666';
  const SITE_URL = process.env.URL || 'http://localhost:3000';

  // Validate that the request is coming from Snipcart
  const response = await fetch(`${API_URL}/api/public/custom-payment-gateway/validate?publicToken=${request.PublicToken}`)

  // Return 404 if the request is not from Snipcart
  if (!response.ok) return {
    statusCode: 404,
    body: ""
  }

  // Create payment method list
  let paymentMethodList: SnipcartPaymentMethod[] = [{
    id: 'sleeky_pay',
    name: 'SleekyPay',
    checkoutUrl: `${SITE_URL}/index.html`,
  }]

  // Return available payment methods
  return {
    statusCode: 200,
    body: JSON.stringify(paymentMethodList)
  };
}
Example #6
Source File: index.ts    From cdk-ec2-key-pair with Apache License 2.0 6 votes vote down vote up
handler = function (
  event: LambdaEvent,
  context: Context,
  callback: Callback
) {
  new CustomResource(context, callback, logger)
    .onCreate(Create)
    .onUpdate(Update)
    .onDelete(Delete)
    .handle(event);
}
Example #7
Source File: index.ts    From cdk-ssm-document with Apache License 2.0 6 votes vote down vote up
handler = function (
  event: LambdaEvent = {},
  context: Context,
  callback: Callback
) {
  event = fixBooleanParameters(event as DocumentEvent);
  new CustomResource(event, context, callback, logger)
    .onCreate(Create)
    .onUpdate(Update)
    .onDelete(Delete)
    .handle(event);
}
Example #8
Source File: addOrder.ts    From Stripe-shop-backend with MIT License 6 votes vote down vote up
addOrder: Handler = (event: APIGatewayEvent | ScheduledEvent, context: Context, callBack: Callback) => {
    const data: Order =  JSON.parse((event as APIGatewayEvent).body);
    const timestamp = new Date().getTime();

    const params: OrdersTable = {
        TableName: process.env.DYNAMODB_TABLE_ORDERS,
        Item: {
            orderId: uuid.v1(),
            customerId: data.customerId,
            products: data.products,
            createdAt: timestamp,
            updatedAt: timestamp,
            status: "ordered",
        },
    };

    dynamoDb.put(params, (error, result) => {
        // handle potential errors
        if (error) {
            return errorHandler(callBack, 'ERROR: Couldn\'t create an order', error );
        }
        return successHandler(callBack, result);
    });
}
Example #9
Source File: cancel.ts    From ethgaswatch with MIT License 6 votes vote down vote up
export async function handler(event: APIGatewayEvent, context: Context) {
    context.callbackWaitsForEmptyEventLoop = false;
    const data = event.queryStringParameters;
    console.log(data);

    if (!data.email || !data.id)
        return { statusCode: 400, body: "Bad Request" };

    const result = await UpdateUserAlert(data.id, { disabled: true });
    if (!result) return { statusCode: 500, body: "Error updating user" };

    return {
        statusCode: 200,
        body: `Ok. Email removed`
    }
}
Example #10
Source File: closerepovotes.ts    From tokenlog with MIT License 6 votes vote down vote up
export async function handler(event: APIGatewayEvent, context: Context) {
  if (event.httpMethod !== 'GET') return { statusCode: 405, body: 'Method Not Allowed' };

  context.callbackWaitsForEmptyEventLoop = false;
  console.log('RECURRING JOB: Close repository votes');
  const data = await repository.GetRepoIssuesWithVotes();
  console.log(data.length, '(open) items with votes');

  const closed = new Array<OrgRepoIssue>();
  for (let index = 0; index < data.length; index++) {
    const repo = data[index];
    try {
      console.log('Checking issue on Github. #' + repo.number, repo.org, repo.repo);
      const issue = await IssueService.GetIssue(repo.org, repo.repo, repo.number);

      if (issue?.state === IssueState.CLOSED) {
        console.log('ISSUE CLOSED. Updating votes');
        await repository.CloseVote(repo.org, repo.repo, repo.number);
        closed.push(repo);
      }
    } catch (e) {
      console.error(e);
      console.log('FAILED to close issue. #' + repo.number, repo.org, repo.repo);
    }
  }

  console.log('FINISHING JOB');
  return {
    statusCode: 200,
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      count: closed.length,
      data: closed,
    }),
  };
}
Example #11
Source File: role-controller.ts    From ddd-cqrs-es-aws-sam with MIT License 6 votes vote down vote up
getHandler = async (event: APIGatewayProxyEvent, context: Context): Promise<APIGatewayProxyResult> => {
  initApplication();

  try {
    _applicationContainer.logger.debug('Role Get Handler Event: %o', event);

    const roleGetDto = Object.assign(new RoleGetDto(), event.pathParameters) as RoleGetDto;
    await validateOrReject(roleGetDto);

    const repository = _applicationContainer.get<ProjectionRepository<RoleProjection>>(DynamoProjectionRepository);
    const roleProjection = await repository.get(process.env.projectionRolesTable, roleGetDto.id);

    return {
      statusCode: roleProjection ? HttpStatus.OK : HttpStatus.NOT_FOUND,
      body: roleProjection ? JSON.stringify(roleProjection) : null
    };
  } catch (error) {
    return ApplicationController.handleError(_applicationContainer, error);
  }
}
Example #12
Source File: importProducts.ts    From Stripe-shop-backend with MIT License 6 votes vote down vote up
importProducts: Handler = (event: APIGatewayEvent | ScheduledEvent, context: Context, callBack: Callback) => {

    const data: ImportProduct =  JSON.parse((event as APIGatewayEvent).body);

    const params: ProductTable = {
        TableName: process.env.DYNAMODB_TABLE_PRODUCTS,
    };

    const errors: string[] = [];
    const results: string[] = [];

    for(let i = 0; i< data.Count; i++) {

        params.Item = data.Items[i];


        dynamoDb.put(params, (error, result) => {
            if (error) {
                errors.push(params.Item.name);
            }
            else {
                results.push(params.Item.name);
            }
        });
    }

    return successHandler(callBack, { errors, results });
}
Example #13
Source File: user-controller.ts    From ddd-cqrs-es-aws-sam with MIT License 6 votes vote down vote up
putHandler = async (event: APIGatewayProxyEvent, context: Context): Promise<APIGatewayProxyResult> => {
  initApplication();

  try {
    _applicationContainer.logger.debug('User Put Handler Event: %o', event);

    const userPutDto = Object.assign(new UserPutDto(), JSON.parse(event.body), event.pathParameters) as UserPutDto;

    await validateOrReject(userPutDto);
    await _applicationContainer.get<UpdateUserHandler>(UpdateUserHandler).handle(new UpdateUser(userPutDto.id, userPutDto.firstName, userPutDto.lastName));

    return { statusCode: HttpStatus.ACCEPTED, body: null };
  } catch (error) {
    return ApplicationController.handleError(_applicationContainer, error);
  }
}
Example #14
Source File: kinesis-stream.service.ts    From nr-apm-stack with Apache License 2.0 6 votes vote down vote up
/* eslint-disable @typescript-eslint/no-unused-vars */
  /**
   * Handle the Kinesis event by transforming and then bulk uploading to OpenSearch
   * @param event The event containing the data to transform
   * @param context The lambda context
   * @returns A promise to wait on
   */
  public async handle(event: KinesisStreamEvent, context: Context): Promise<OpenSearchBulkResult> {
    this.logger.log(`Transforming ${event.Records.length} kinesis records to ES documents`);
    const docs = this.ecsTransformService.transform(event);
    this.logger.log(`Submitting ${docs.length} documents to ES`);
    return this.openSearch.bulk(docs).then((value) => {
      this.logger.log(`${docs.length - value.errors.length} documents added`);
      this.logger.log(`${value.errors.length} documents failed`);
      return value;
    });
  }
Example #15
Source File: getBusinesses.ts    From Stripe-shop-backend with MIT License 6 votes vote down vote up
getBusinesses: Handler = (event: APIGatewayEvent | ScheduledEvent, context: Context, callBack: Callback) => {

    const data =  JSON.parse((event as APIGatewayEvent).body);
    const params = {
        TableName: process.env.DYNAMODB_TABLE_BUSINESSES,
        Select: 'ALL_ATTRIBUTES',
    };

    dynamoDb.scan(params, (error, result) => {
        if (error) {
            console.error(error);
            return errorHandler(callBack, 'ERROR: Couldn\'t fetch the business', error );
        }
        return successHandler(callBack, result);
    });
}
Example #16
Source File: lambda.ts    From iplocate with MIT License 6 votes vote down vote up
handler = (
  event: APIGatewayProxyEvent,
  context: Context,
  cb: Callback
) => {
  context.callbackWaitsForEmptyEventLoop = false;
  app.ready((e) => {
    if (e) return console.error(e.stack || e);
    awsServerlessExpress.proxy(server, event, context, "CALLBACK", cb);
  });
}
Example #17
Source File: user-controller.ts    From ddd-cqrs-es-aws-sam with MIT License 6 votes vote down vote up
removeRoleHandler = async (event: APIGatewayProxyEvent, context: Context): Promise<APIGatewayProxyResult> => {
  initApplication();

  try {
    _applicationContainer.logger.debug('Remove Role Handler Event: %o', event);

    const userRemoveRoleDto = Object.assign(new UserRemoveRoleDto(), event.pathParameters) as UserRemoveRoleDto;

    await validateOrReject(userRemoveRoleDto);
    await _applicationContainer.get<RemoveUserRoleHandler>(RemoveUserRoleHandler).handle(new RemoveUserRole(userRemoveRoleDto.id, userRemoveRoleDto.roleId));

    return { statusCode: HttpStatus.ACCEPTED, body: null };
  } catch (error) {
    return ApplicationController.handleError(_applicationContainer, error);
  }
}
Example #18
Source File: updatePaymentIntent.ts    From Stripe-shop-backend with MIT License 5 votes vote down vote up
createPaymentIntent: Handler = async (event: APIGatewayEvent | ScheduledEvent, context: Context, callBack: Callback) => {
    // @ts-ignore
    const stripe = new Stripe(process.env.STRIPE_API_KEY, {
        apiVersion: process.env.STRIPE_API_VERSION,
        typescript: true,
    });
    const requestData: any = JSON.parse((event as APIGatewayEvent).body);

    // @todo validation on inputs
    const {
        amount,
        currency,
        payment_method_types,
        capture_method,
        off_session,
    } = requestData;

    const valid_payment_method_types = (payment_method_types) ? payment_method_types : ['card'];
    const valid_capture_method = (capture_method == 'manual') ? capture_method : 'automatic';
    // const valid_setup_future_usage = (off_session) ? 'off_session' : 'on_session';
    try {
        const paymentIntent = await stripe.paymentIntents.create({
            amount,
            currency,
            payment_method_types: valid_payment_method_types,
            capture_method: valid_capture_method,
            // setup_future_usage: valid_setup_future_usage,
        });
        return callBack(null, {
            statusCode: 200,
            headers: {
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Credentials': true,
            },
            body: JSON.stringify({
                    message: 'Payment Intent Created!',
                    PaymentIntent: paymentIntent,
                },
                null,
                2,
            ),
        });
    }
    catch(error) {
        callBack(null,{
            statusCode: 500,
            headers: {
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Credentials': true,
            },
            body: JSON.stringify({
                    message: 'ERROR Payment Intent Creation FAILED!',
                    errorDetails: error,
                },
                null,
                2,
            ),
        });
    }
}
Example #19
Source File: lambda.ts    From office-booker with MIT License 5 votes vote down vote up
handler = async (event: LogGroupEvent | undefined, context: Context) => {
  const env = process.env.ENV;
  if (env === undefined) {
    console.error('ENV not defined');
  } else {
    await processEvent(fetch, env, event);
  }
}
Example #20
Source File: handler.ts    From sourcestack with MIT License 5 votes vote down vote up
handler = (event: any, context: Context) => proxy(server, event, context)
Example #21
Source File: cancelPaymentIntent.ts    From Stripe-shop-backend with MIT License 5 votes vote down vote up
cancelPaymentIntent: Handler = async (event: APIGatewayEvent | ScheduledEvent, context: Context, callBack: Callback) => {
    const stripe = new Stripe(process.env.STRIPE_API_KEY, {
        apiVersion: process.env.STRIPE_API_VERSION,
        typescript: true,
    });

    const requestData: any = JSON.parse((event as APIGatewayEvent).body);

    const { piid, cancellation_reason } = requestData;
    if (! piid) {
        return callBack('Must provide the PaymentIntentID');
    }

    const reason: Stripe.PaymentIntentCancelParams.CancellationReason = cancellation_reason ?? 'abandoned';

    try {
        const paymentIntent = await stripe.paymentIntents.cancel(piid, {
            cancellation_reason: reason
        });

        return callBack(null, {
            statusCode: 200,
            headers: {
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Credentials': true,
            },
            body: JSON.stringify({
                    message: 'Payment cancelled!',
                    PaymentIntent: paymentIntent,
                },
                null,
                2,
            ),
        });
    }
    catch(error) {
        return callBack(null, {
            statusCode: 500,
            headers: {
                'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Credentials': true,
            },
            body: JSON.stringify({
                    message: 'ERROR Payment Intent Cancellation FAILED!',
                    errorDetails: error,
                },
                null,
                2,
            ),
        });
    }
}
Example #22
Source File: test.ts    From MDDL with MIT License 5 votes vote down vote up
createMockContext = (): Context =>
  (jest.fn() as unknown) as Context
Example #23
Source File: average.ts    From ethgaswatch with MIT License 5 votes vote down vote up
export async function handler(event: APIGatewayEvent, context: Context) {
  context.callbackWaitsForEmptyEventLoop = false;

  const days = 7
  const hours = 24
  const total = days * hours
  const gasData = await GetHourlyAverage(total)
  const xDayOfTheWeek = new Array(days).fill(0).map((_, i) => moment().subtract(i, 'd').format('dddd')).reverse()
  const weekDays = xDayOfTheWeek.map((i) => moment().day(i).weekday())
  const yHoursInTheDay = new Array(hours).fill(0).map((_, i) => `${i}:00`)
  const hoursInTheDay = new Array(hours).fill(0).map((_, i) => i)

  // mongo days = 1-7 (starting at Sunday)
  // moment days = 0-6 (starting at Sunday)

  const current = moment()
  const data = hoursInTheDay
    .map((hourOfTheDay) => {
      return weekDays
        .map((weekDay) => {
          // timezones? GMT ?
          if (weekDay === current.weekday() && hourOfTheDay > current.hour() - 1) {
            return null
          }

          const value = gasData.find(i => i.day === (weekDay + 1) && i.hour === hourOfTheDay)
          return value ? Math.floor(value.avg) : undefined
        })
    }
  )

  const response = {
    x: xDayOfTheWeek,
    y: yHoursInTheDay,
    data
  }

  return {
      statusCode: 200,
      body: JSON.stringify(response),
  }
}
Example #24
Source File: confirm-payment.ts    From sleekypay with MIT License 5 votes vote down vote up
exports.handler = async function (
  event: APIGatewayEvent,
  context: Context,
  callback: Callback) {
  interface ConfirmResult {
    returnUrl: string;
  }

  const requestBody = JSON.parse(event.body);
  const paymentId = uuid();

  const API_URL = process.env.API_URL || 'https://localhost:12666';
  const SITE_URL = process.env.URL || event.headers.origin;

  const response = await fetch(
    `${API_URL}/api/private/custom-payment-gateway/payment`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.BEARER_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      paymentSessionId: requestBody.paymentSessionId,
      state: requestBody.state,
      error: requestBody.error,
      transactionId: paymentId,
      instructions: 'Your payment will appear on your statement in the coming days',
      links: {
        refunds: `${SITE_URL}/.netlify/functions/refund-payment?transactionId=${paymentId}`,
      }
    }),
  });

  if (response.ok) {
    const body = (await response.json()) as ConfirmResult;

    return {
      statusCode: 200,
      body: JSON.stringify({ ok: true, returnUrl: body.returnUrl })
    };
  }
}
Example #25
Source File: settings.ts    From tokenlog with MIT License 5 votes vote down vote up
export async function handler(event: APIGatewayEvent, context: Context) {
  if (event.httpMethod !== 'GET') return { statusCode: 405, body: 'Method Not Allowed' };
  context.callbackWaitsForEmptyEventLoop = false;

  const owner = event.queryStringParameters?.owner ?? '';
  const repo = event.queryStringParameters?.repo ?? '';
  if (!owner || !repo) return { statusCode: 400, body: 'Bad Request' };

  let chainId = 1;
  if (event.queryStringParameters?.chainId && !isNaN(Number(event.queryStringParameters?.chainId))) {
    chainId = Number(event.queryStringParameters?.chainId);
  }

  const cacheKey = `repoSettings::${owner}-${repo}-${chainId}`;
  console.log('GET RepositorySettings', owner, repo);

  if (repositorySettings[cacheKey]) {
    console.log('RETURN Cached settings');
    return {
      statusCode: 200,
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(repositorySettings[cacheKey]),
    };
  }

  let settings = RepoConfigs.find((i) => i.org === owner && i.repo === repo) as RepositorySettings;
  if (!settings) {
    try {
      const octokit = new Octokit({
        auth: AppConfig.GITHUB_ACCESS_TOKEN,
      });
      const result: any = await octokit.repos.getContent({ owner, repo, path: 'tokenlog.json' });
      if (result.status !== 200) throw new Error("Couldn't retrieve tokenlog config");

      const content = Buffer.from(result.data.content, 'base64').toString();
      settings = JSON.parse(content) as RepositorySettings;
    } catch {
      console.error("Couldn't retrieve tokenlog config. The file likely doesn't exist at the requested repository.");
    }
  }

  if (settings) {
    const chain = settings.chainId || chainId;
    if (settings.tokenAddress) {
      console.log('GET TokenInfo', settings.tokenAddress, chain);
      settings.token = await VotingService.GetTokenInfo(settings.tokenAddress, chain);
    } else if (settings.tokenAddresses) {
      const tokens = new Array<Token>();

      for (let index = 0; index < settings.tokenAddresses.length; index++) {
        const address = settings.tokenAddresses[index];
        console.log('GET TokenInfo', address, chain);
        const token = await VotingService.GetTokenInfo(address, chain);
        if (token) {
          tokens.push(token);
        }
      }

      settings.tokens = tokens;
    }
  }

  repositorySettings[cacheKey] = settings;
  console.log('CACHE RepositorySettings', cacheKey, repositorySettings[cacheKey]);
  return {
    statusCode: 200,
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(settings),
  };
}
Example #26
Source File: kinesis-stream.service.spec.ts    From nr-apm-stack with Apache License 2.0 5 votes vote down vote up
describe('KinesisStreamService', () => {
  it('transforms and then sends data', async () => {
    const docs = ['docs', 'docs', 'docs!'];
    const etService = {
      transform: jest.fn().mockReturnValue(docs),
    } as unknown as EcsTransformService;
    const osService = {
      bulk: jest.fn().mockReturnValue({
        then: jest.fn().mockImplementation((cb) => {
          cb({
            errors: ['err'],
          });
        }),
      }),
    } as unknown as OpenSearchService;
    const logger = {
      log: jest.fn(),
      debug: jest.fn(),
    } as LoggerService;

    const ks = new KinesisStreamService(
      etService,
      osService,
      logger,
    );
    const fakeEvent = {Records: []} as KinesisStreamEvent;
    const fakeContext = {} as Context;

    await ks.handle(fakeEvent, fakeContext);

    expect(etService.transform).toBeCalledTimes(1);
    expect(etService.transform).toBeCalledWith(fakeEvent);

    expect(osService.bulk).toBeCalledTimes(1);
    expect(osService.bulk).toBeCalledWith(docs);
    expect(logger.log).toBeCalledTimes(4);
    expect(logger.log).toBeCalledWith('Transforming 0 kinesis records to ES documents');
    expect(logger.log).toBeCalledWith('Submitting 3 documents to ES');
    expect(logger.log).toBeCalledWith('2 documents added');
    expect(logger.log).toBeCalledWith('1 documents failed');
  });
});
Example #27
Source File: vote.ts    From tokenlog with MIT License 5 votes vote down vote up
export async function handler(event: APIGatewayEvent, context: Context) {
  if (event.httpMethod !== 'POST') return { statusCode: 405, body: 'Method Not Allowed' };

  const org = event.queryStringParameters?.org ?? '';
  const repo = event.queryStringParameters?.repo ?? '';
  if (!org || !repo) return { statusCode: 400, body: 'Bad Request' };

  const body = event.body ? (JSON.parse(event.body) as Vote) : undefined;
  if (!body) return { statusCode: 400, body: 'Bad Request' };

  context.callbackWaitsForEmptyEventLoop = false;

  let vp: VotingPower | undefined = undefined;
  if (body.tokenAddress.includes('|')) {
    vp = await VotingService.GetCombinedVotingPower(
      body.tokenAddress.split('|').map((i) => {
        return {
          address: i,
          name: i,
          symbol: '',
          totalSupply: -1,
          decimals: -1,
        };
      }),
      body.org,
      body.repo,
      body.address,
      body.chainId
    );
  } else {
    vp = await VotingService.GetVotingPower(body.tokenAddress, body.org, body.repo, body.address, body.chainId);
  }

  if (!vp) {
    return { statusCode: 500, body: 'Unable to retrieve voting power.' };
  }

  // VotingPower will not include already casted votes, due to bad design in the services/REST calls
  console.log('Getting already cast user votes');
  const alreadyUsedVotes = await repository.GetUserVotes(body.org, body.repo, body.address);
  vp = {
    totalPower: vp.totalPower,
    voted: alreadyUsedVotes,
    available: vp.totalPower - alreadyUsedVotes,
    totalSupply: vp.totalSupply,
  };

  if (body.cost > vp.available) {
    console.log('Not enough voting power left. Unable to cast vote.');
    return { statusCode: 500, body: 'Not enough voting power left. Unable to cast vote.' };
  }

  const data = await repository.CreateVote(body);

  return {
    statusCode: 200,
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(data),
  };
}