I'm just starting out writing React app to mint NFTs, I have a minting function that works but I am trying to work out how I set a mint value within the RPC call?
const MintingTool = (props) => {
const mintNFT = async () => {
await window.contract.nft_mint(
{
token_id: `TokenID-${small_id }`,
metadata: {
title: " My NF Token",
description: "Some description",
tier:"Gold",
media:
"https://...../",
},
receiver_id: window.accountId,
},
300000000000000, // attached GAS (optional)
new BN("1000000000000000000000000")
);
};
Any ideas?
Related
I'm developing a little CDKv2 script to instantiate a few AWS services.
I have some lambda code deployed in the lambda/ folder and the frontend stored in a bucket populated using the frontend/ folder in the source.
I've noticed that whenever I make a change to any of the file inside these two, cdk watch return the following error and falls back to perform a full redeploy (which is significantly slow).
Could not perform a hotswap deployment, because the CloudFormation template could not be resolved: Parameter or resource 'DomainPrefix' could not be found for evaluation
Falling back to doing a full deployment
Is there any way to make changes in these folders only trigger updating the related bucket content or the related lambda?
Following here the stack.ts for quick reference, just in case here you can take a look at the repo.
export class CdkAuthWebappStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const domainPrefixParam = new CfnParameter(this, 'DomainPrefix', {
type: 'String',
description: 'You have to set it in google cloud as well', //(TODO: add link to explain properly)
default: process.env.DOMAIN_NAME || ''
})
const googleClientIdParam = new CfnParameter(this, 'GoogleClientId', {
type: 'String',
description: 'From google project',
noEcho: true,
default: process.env.GOOGLE_CLIENT_ID || ''
})
const googleClientSecretParam = new CfnParameter(this, 'GoogleClientSecret', {
type: 'String',
description: 'From google project',
noEcho: true,
default: process.env.GOOGLE_CLIENT_SECRET || ''
})
if(!domainPrefixParam.value || !googleClientIdParam.value || !googleClientSecretParam.value){
throw new Error('Make sure you initialized DomainPrefix, GoogleClientId and GoogleClientSecret in the stack parameters')
}
const s3frontend = new s3.Bucket(this, 'Bucket', {
bucketName: domainPrefixParam.valueAsString+'-frontend-bucket',
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
encryption: s3.BucketEncryption.S3_MANAGED,
enforceSSL: true,
versioned: false,
removalPolicy: cdk.RemovalPolicy.DESTROY,
autoDeleteObjects: true,
websiteIndexDocument: "index.html",
});
//TODO: fare in modo che questa origin access identity non sia legacy quando deployo
const cfdistributionoriginaccessidentity = new cloudfront.OriginAccessIdentity(this, 'CFOriginAccessIdentity', {
comment: "Used to give bucket read to cloudfront"
})
const cfdistribution = new cloudfront.CloudFrontWebDistribution(this, 'CFDistributionFrontend', {
originConfigs: [
{
s3OriginSource: {
s3BucketSource: s3frontend,
originAccessIdentity: cfdistributionoriginaccessidentity
},
behaviors: [{
isDefaultBehavior: true,
allowedMethods: cloudfront.CloudFrontAllowedMethods.GET_HEAD_OPTIONS,
forwardedValues: {
queryString: true,
cookies: { forward: 'all' }
},
minTtl: cdk.Duration.seconds(0),
defaultTtl: cdk.Duration.seconds(3600),
maxTtl: cdk.Duration.seconds(86400)
}]
}
]
})
s3frontend.grantRead(cfdistributionoriginaccessidentity)
const cfdistributionpolicy = new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['cloudfront:CreateInvalidation'],
resources: [`"arn:aws:cloudfront::${this.account}:distribution/${cfdistribution.distributionId}"`]
});
const userpool = new cognito.UserPool(this, 'WebAppUserPool', {
userPoolName: 'web-app-user-pool',
selfSignUpEnabled: false
})
const userpoolidentityprovidergoogle = new cognito.UserPoolIdentityProviderGoogle(this, 'WebAppUserPoolIdentityGoogle', {
clientId: googleClientIdParam.valueAsString,
clientSecret: googleClientSecretParam.valueAsString,
userPool: userpool,
attributeMapping: {
email: cognito.ProviderAttribute.GOOGLE_EMAIL
},
scopes: [ 'email' ]
})
// this is used to make the hostedui reachable
userpool.addDomain('Domain', {
cognitoDomain: {
domainPrefix: domainPrefixParam.valueAsString
}
})
const CLOUDFRONT_PUBLIC_URL = `https://${cfdistribution.distributionDomainName}/`
const client = userpool.addClient('Client', {
oAuth: {
flows: {
authorizationCodeGrant: true
},
callbackUrls: [
CLOUDFRONT_PUBLIC_URL
],
logoutUrls: [
CLOUDFRONT_PUBLIC_URL
],
scopes: [
cognito.OAuthScope.EMAIL,
cognito.OAuthScope.OPENID,
cognito.OAuthScope.PHONE
]
},
supportedIdentityProviders: [
cognito.UserPoolClientIdentityProvider.GOOGLE
]
})
client.node.addDependency(userpoolidentityprovidergoogle)
// defines an AWS Lambda resource
const securedlambda = new lambda.Function(this, 'AuhtorizedRequestsHandler', {
runtime: lambda.Runtime.NODEJS_14_X,
code: lambda.Code.fromAsset('lambda'),
handler: 'secured.handler'
});
const lambdaapiintegration = new apigw.LambdaIntegration(securedlambda)
const backendapigw = new apigw.RestApi(this, 'AuthorizedRequestAPI', {
restApiName: domainPrefixParam.valueAsString,
defaultCorsPreflightOptions: {
"allowOrigins": apigw.Cors.ALL_ORIGINS,
"allowMethods": apigw.Cors.ALL_METHODS,
}
})
const backendapiauthorizer = new apigw.CognitoUserPoolsAuthorizer(this, 'BackendAPIAuthorizer', {
cognitoUserPools: [userpool]
})
const authorizedresource = backendapigw.root.addMethod('GET', lambdaapiintegration, {
authorizer: backendapiauthorizer,
authorizationType: apigw.AuthorizationType.COGNITO
})
const s3deploymentfrontend = new s3deployment.BucketDeployment(this, 'DeployFrontEnd', {
sources: [
s3deployment.Source.asset('./frontend'),
s3deployment.Source.data('constants.js', `const constants = {domainPrefix:'${domainPrefixParam.valueAsString}', region:'${this.region}', cognito_client_id:'${client.userPoolClientId}', apigw_id:'${backendapigw.restApiId}'}`)
],
destinationBucket: s3frontend,
distribution: cfdistribution
})
new cdk.CfnOutput(this, 'YourPublicCloudFrontURL', {
value: CLOUDFRONT_PUBLIC_URL,
description: 'Navigate to the URL to access your deployed application'
})
}
}
Recording the solution from the comments:
Cause:
cdk watch apparently does not work with template parameters. I guess this is because the default --hotswap option bypasses CloudFormation and deploys instead via SDK commands.
Solution:
Remove the CfnParamters from the template. CDK recommends not using parameters in any case.
Perhaps cdk watch --no-hotswap would also work?
I want to send voip push to my iOS app when its not active, and I tried to use apn module from this solution but it did not work for me.
I followed official apple docs about voip push here but still have some problems to send it from the server.
I also tried to send it trough AWS sns service but got normal push for notification and etc.
What do I do wrong?
Right now my code is :
here I do format for sns item
const formatVoipPushNotificationsToSend = (type, header, launchId, sender, to = '', device_token, token) => {
const headers = {
':method': 'POST',
'apns-topic': '************.voip', //application bundle ID
':scheme': 'https',
':path': `/3/device/${device_token}`,
'authorization': `bearer ${token}`,
'apns-push-type': 'voip',
};
const aps = {
alert: {
title: header,
body: 'text' || null
},
itemId: type,
from: sender || null,
to,
launchId: launchId || null,
'content-available': 1
};
return { aps, headers };
};
and then I pass the item here and send it to the app with sns endpoint.
const pushNotifications = (item, arn, userId) => {
const payload = JSON.stringify(item);
const snsMessage = {};
snsMessage[SNS_PAYLOAD_KEY] = payload;
const params = {
Message: JSON.stringify(snsMessage),
TargetArn: arn,
MessageStructure: 'json'
};
const eventBody = item.aps.itemId ? {
[EVENT_TYPES.PUSH_SEND]: item.aps.itemId
} : {};
AmplitudeService.logEvent(EVENT_TYPES.PUSH_SEND, userId, eventBody);
return snsClient.publish(params).promise();
};
I'm using a slightly different approach:
var apn = require('apn');
const { v4: uuidv4 } = require('uuid');
const options = {
token: {
key: 'APNKey.p8',
keyId: 'S83SFJIE38',
teamId: 'JF982KSD6f'
},
production: false
};
var apnProvider = new apn.Provider(options);
// Sending the voip notification
let notification = new apn.Notification();
notification.body = "Hello there!";
notification.topic = "com.myapp.voip";
notification.payload = {
"aps": { "content-available": 1 },
"handle": "1111111",
"callerName": "Richard Feynman",
"uuid": uuidv4()
};
apnProvider.send(notification, deviceToken).then((response) => {
console.log(response);
});
Hello I have a problem when I deploy my application in vercel, I am creating a function without server that brings me the data of a collection in mongodb, using mongoose. In local everything works fine but when I deploy the function it gives me this error:
504: GATEWAY_TIMEOUT
Code: FUNCTION_INVOCATION_TIMEOUT
ID: gru1 :: 594vg-1620811347355-66f311d5c992
I understand that the free plan of vercel allows you to create functions with a maximum of 10 seconds of waiting, is this why I get the error? Or it may be for one of these reasons: https://vercel.com/support/articles/why-does-my-serverless-function-work-locally-but-not-when-deployed
Serverless function:
import mongoose from "mongoose";
module.exports = function(req, res) {
const Schema = mongoose.Schema;
const inmuebleSchema = new Schema({
user_id: String, //{type: Schema.Types.ObjectId, ref: 'User'}
desc: String,
tipo_propiedad: { type: String, enum: ["casa", "quinta", "departamento"] },
amb: Number,
estado: { type: String, enum: ["venta", "alquiler"] },
banios: Number,
dorm: Number,
coch: Number,
direc: String,
precio: String,
images: { type: Array, default: [] },
uploadedDate: { type: Date, default: Date.now() }
});
const Inmueble = mongoose.model("inmueble", inmuebleSchema);
mongoose
.connect(process.env.MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => {
Inmueble.find()
.exec()
.then(inmuebles => res.json({ inmuebles }))
.catch(err => res.json({ status: "error" }));
})
.catch(err => {
res.status(500);
});
};
The problem was, I wasn't adding my site's IP to my cluster's whitelist.
To send a silent remote notification to my iOS app from Google Firebase Functions, this is my index.js file:
const functions = require('firebase-functions');
const admin = require('firebase-admin')
admin.initializeApp();
const messaging = admin.messaging();
exports.sendPushNotification = functions.https.onRequest((req, res) => {
var payload = {
"notification": {
title: 'test title 2',
body: 'test body 2.1',
icon: 'https://i.pinimg.com/236x/2f/b9/bd/2fb9bd91b530d20410744249a418240b.jpg'
}
"data": {
"aps" = {
"content-available" : 1,
};
}
}
messaging.sendToTopic("backgroundUpdate", payload).then(function (response) {
console.log(response);
res.send(response);
}).catch(e => {
console.log(e)
res.send(e)
})
});
But Google keeps giving me this error message:
Deployment failure:
Build failed: /workspace/index.js:13
"data": { ^^^^^^ SyntaxError: Unexpected string at new Script (vm.js:83:7) at checkScriptSyntax (internal/bootstrap/node.js:620:5) at startup (internal/bootstrap/node.js:280:11) at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3); Error ID: d984e68f
Can anyone point me to my error? I have not been able to find a solution.
For some time I have been trying to find a solution to my problem, however, nothing has worked so far. I'm working on Ionic 4 application with Angular 8 and Ngrx. I created #Effect that calling a service which calling http service and then I need to dispatch two actions. One of them have a payload also.
Everything working fine in development (browsers). I've tried on Chrome, Firefox, Safari. Problem is appearing when I'm trying on the iPhone. On the iPhone payload sending to action is empty object {} instead of object with proper fields.
I've tried to build in non-production mode, disabling aot, build-optimizer, optimization.
Store init:
StoreModule.forFeature('rental', reducer),
EffectsModule.forFeature([RentalServiceEffect]),
Store:
export interface Contract {
address: string;
identity: string;
endRentSignature?: string;
}
export interface RentalStoreState {
status: RentStatus;
contract?: Contract;
metadata?: RentalMetadata;
summary?: RentalSummary;
carState?: CarState;
}
export const initialState: RentalStoreState = {
status: RentStatus.NOT_STARTED,
contract: {
address: null,
identity: null,
endRentSignature: null,
},
};
Action:
export const rentVerified = createAction(
'[RENTAL] RENT_VERIFIED',
(payload: Contract) => ({ payload })
);
Reducer:
const rentalReducer = createReducer(
initialState,
on(RentActions.rentVerified, (state, { payload }) => ({
...state,
contract: payload,
status: RentStatus.RENT_VERIFIED
})));
export function reducer(state: RentalStoreState | undefined, action: Action) {
return rentalReducer(state, action);
}
Method from a service:
public startRentalProcedure(
vehicle: Vehicle,
loading: any
): Observable<IRentalStartResponse> {
loading.present();
return new Observable(observe => {
const id = '';
const key = this.walletService.getActiveAccountId();
this.fleetNodeSrv
.startRent(id, key, vehicle.id)
.subscribe(
res => {
loading.dismiss();
observe.next(res);
observe.complete();
},
err => {
loading.dismiss();
observe.error(err);
observe.complete();
}
);
});
}
Problematic effect:
#Effect()
public startRentalProcedure$ = this.actions$.pipe(
ofType(RentalActions.startRentVerifying),
switchMap(action => {
return this.rentalSrv
.startRentalProcedure(action.vehicle, action.loading)
.pipe(
mergeMap(response => {
return [
RentalActions.rentVerified({
address: response.address,
identity: response.identity
}),
MainActions.rentalProcedureStarted()
];
}),
catchError(err => {
this.showConfirmationError(err);
return of({ type: '[RENTAL] START_RENTAL_FAILED' });
})
);
})
);