Implement payments for app deployments #17
@ -5,7 +5,7 @@ import { Octokit } from 'octokit';
|
||||
import { inc as semverInc } from 'semver';
|
||||
import { DeepPartial } from 'typeorm';
|
||||
|
||||
import { Account, Registry as LaconicRegistry, getGasPrice, parseGasAndFees } from '@cerc-io/registry-sdk';
|
||||
import { Account, Registry as LaconicRegistry, getGasPrice, parseGasAndFees, IndexedTx } from '@cerc-io/registry-sdk';
|
||||
|
||||
import { RegistryConfig } from './config';
|
||||
import {
|
||||
@ -505,6 +505,15 @@ export class Registry {
|
||||
return account.address;
|
||||
}
|
||||
|
||||
async getTxResponse(txHash: string): Promise<IndexedTx | null> {
|
||||
const account = new Account(Buffer.from(this.registryConfig.privateKey, 'hex'));
|
||||
await account.init();
|
||||
const laconicClient = await this.registry.getLaconicClient(account);
|
||||
const txResponse: IndexedTx | null = await laconicClient.getTx(txHash);
|
||||
|
||||
return txResponse;
|
||||
}
|
||||
|
||||
getLrn(appName: string): string {
|
||||
assert(this.registryConfig.authority, "Authority doesn't exist");
|
||||
return `lrn://${this.registryConfig.authority}/applications/${appName}`;
|
||||
|
@ -84,6 +84,17 @@ export const createResolvers = async (service: Service): Promise<any> => {
|
||||
address: async (_: any, __: any, context: any) => {
|
||||
return service.getAddress();
|
||||
},
|
||||
|
||||
verifyTx: async (
|
||||
_: any,
|
||||
{
|
||||
txHash,
|
||||
amount,
|
||||
senderAddress,
|
||||
}: { txHash: string; amount: string; senderAddress: string },
|
||||
) => {
|
||||
return service.verifyTx(txHash, amount, senderAddress);
|
||||
},
|
||||
},
|
||||
|
||||
// TODO: Return error in GQL response
|
||||
|
@ -265,6 +265,7 @@ type Query {
|
||||
domains(projectId: String!, filter: FilterDomainsInput): [Domain]
|
||||
deployers: [Deployer]
|
||||
address: String!
|
||||
verifyTx(txhash: String!, amount: String!, senderAddress: String!): Boolean!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
|
@ -1405,4 +1405,26 @@ export class Service {
|
||||
async getAddress(): Promise<any> {
|
||||
return this.laconicRegistry.getAddress();
|
||||
}
|
||||
|
||||
async verifyTx(txhash: string, amountSent: string, senderAddress: string): Promise<boolean> {
|
||||
const txResponse = await this.laconicRegistry.getTxResponse(txhash);
|
||||
if (!txResponse) {
|
||||
log('Transaction response not found');
|
||||
return false;
|
||||
}
|
||||
|
||||
const transfer = txResponse.events.find(e => e.type === 'transfer' && e.attributes.some(a => a.key === 'msg_index'));
|
||||
if (!transfer) {
|
||||
log('No transfer event found');
|
||||
return false;
|
||||
}
|
||||
|
||||
const sender = transfer.attributes.find(a => a.key === 'sender')?.value;
|
||||
const recipient = transfer.attributes.find(a => a.key === 'recipient')?.value;
|
||||
const amount = transfer.attributes.find(a => a.key === 'amount')?.value;
|
||||
|
||||
const recipientAddress = await this.getAddress();
|
||||
|
||||
return amount === amountSent && sender === senderAddress && recipient === recipientAddress;
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ import {
|
||||
ArrowRightCircleFilledIcon,
|
||||
LoadingIcon,
|
||||
} from 'components/shared/CustomIcon';
|
||||
import { Checkbox } from 'components/shared/Checkbox';
|
||||
import { Button } from 'components/shared/Button';
|
||||
import { useToast } from 'components/shared/Toast';
|
||||
|
||||
@ -169,15 +168,6 @@ const CreateRepo = () => {
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Controller
|
||||
name="isPrivate"
|
||||
control={control}
|
||||
render={({}) => (
|
||||
<Checkbox label="Make this repo private" disabled={true} />
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
{...buttonSize}
|
||||
|
@ -440,4 +440,22 @@ export class GQLClient {
|
||||
|
||||
return data.address;
|
||||
}
|
||||
|
||||
async verifyTx(txhash: string, amount: string, senderAddress: string): Promise<boolean> {
|
||||
console.log('Verifying Transaction with parameters:', {
|
||||
txhash,
|
||||
amount,
|
||||
senderAddress
|
||||
});
|
||||
const { data } = await this.client.query({
|
||||
query: queries.verifyTx,
|
||||
variables: {
|
||||
txhash,
|
||||
amount,
|
||||
senderAddress
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
@ -329,3 +329,9 @@ query {
|
||||
address
|
||||
}
|
||||
`;
|
||||
|
||||
export const verifyTx = gql`
|
||||
query ($txhash: String!, $amount: String!, $senderAddress: String!) {
|
||||
verifyTx(txhash: $txhash, amount: $amount, senderAddress: $senderAddress)
|
||||
}
|
||||
`;
|
||||
|
Loading…
Reference in New Issue
Block a user