Skip to content

Commit

Permalink
Add farm confirmation notifications (#4)
Browse files Browse the repository at this point in the history
* Update monitor dependency

* Split apis

* Add dialect connection

* Add quarry events listener implementation

* Implement monitor draft

* Implement farm monitor

* Fetch owner form mergemine

* Adjust notification format

* Fix to staked token.

Co-authored-by: Alexey Tsymbal <[email protected]>
Co-authored-by: cbosborn <[email protected]>
  • Loading branch information
3 people authored May 25, 2022
1 parent 6e7cf80 commit e6cbb52
Show file tree
Hide file tree
Showing 18 changed files with 702 additions and 154 deletions.
30 changes: 24 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,32 @@ yarn

### Running locally

#### generate a new keypair for friktion monitoring service and fund it

```bash
export keypairs_dir=~/projects/dialect
solana-keygen new --outfile ${keypairs_dir}/saber-service-dev-local-key.json
solana-keygen pubkey ${keypairs_dir}/saber-service-dev-local-key.json > ${keypairs_dir}/saber-service-dev-local-key.pub
solana -k ${keypairs_dir}/saber-service-dev-local-key.json airdrop 300

#### start server (test mode)

```shell
MAINNET_RPC_URL=rpcUrl \
TWITTER_APP_KEY=appKey \
TWITTER_APP_SECRET=appSecret \
TWITTER_ACCESS_TOKEN=accessToken \
TWITTER_ACCESS_SECRET=accessSecret \
export keypairs_dir=~/projects/dialect
TEST_MODE=true \
WHALE_MONITOR_THRESHOLD=5000 \
yarn start:dev
RPC_URL= \
QUARRY_RPC_URL= \
NETWORK_NAME=localnet \
PRIVATE_KEY=$(cat ${keypairs_dir}/saber-service-dev-local-key.json) yarn start:dev
```

#### start clients

```shell
export keypairs_dir=~/projects/dialect
MONITORING_SERVICE_PUBLIC_KEY=$(cat ${keypairs_dir}/saber-service-dev-local-key.pub) ts-node test/saber-clients.ts
```

### Containerization
Expand Down
19 changes: 13 additions & 6 deletions deployment/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,30 +30,37 @@ spec:
- env:
- name: WHALE_MONITOR_THRESHOLD
value: "4000000"
- name: MAINNET_RPC_URL
- name: NETWORK_NAME
value: "mainnet"
- name: RPC_URL
valueFrom:
secretKeyRef:
key: MAINNET_RPC_URL
key: MAINNET_RPC_URL2
name: env-vars
- name: TWITTER_APP_KEY
valueFrom:
secretKeyRef:
key: TWITTER_APP_KEY
key: SABERWARS_TWITTER_APP_KEY
name: env-vars
- name: TWITTER_APP_SECRET
valueFrom:
secretKeyRef:
key: TWITTER_APP_SECRET
key: SABERWARS_TWITTER_APP_SECRET
name: env-vars
- name: TWITTER_ACCESS_TOKEN
valueFrom:
secretKeyRef:
key: TWITTER_ACCESS_TOKEN
key: SABERWARS_TWITTER_ACCESS_TOKEN
name: env-vars
- name: TWITTER_ACCESS_SECRET
valueFrom:
secretKeyRef:
key: TWITTER_ACCESS_SECRET
key: SABERWARS_TWITTER_ACCESS_SECRET
name: env-vars
- name: PRIVATE_KEY
valueFrom:
secretKeyRef:
key: SABER_MESSAGING_PRIVATE_KEY
name: env-vars
image: dialectlab/saber-monitoring-service:0.0.1
imagePullPolicy: Always
Expand Down
43 changes: 43 additions & 0 deletions examples/quarry-events-example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { QuarryEventSubscription } from '../src/saber-wars-api/quarry-event-api';
import { getOwner, quarrySDK } from '../src/saber-wars-api/quarry-sdk-factory';
import { getTokenInfo } from '../src/saber-wars-api/token-info-api';
import { toDecimals } from '../src/saber-wars-api/saber-wars-api';

const numberFormat = new Intl.NumberFormat('en-US');

async function main() {
const defaultSubscription = new QuarryEventSubscription(
quarrySDK.programs.Mine,
async (evt) => {
const resourceId = await getOwner(evt.data.authority);
if (
resourceId.toBase58() !== 'GNisgcTZZ2WS5PFAEkVUbFso3wNe22cjhmZiEjGcqeHD'
) {
return;
}
if (evt.name === 'StakeEvent') {
console.log(JSON.stringify(evt));
const tokenInfo = await getTokenInfo(evt.data.token);
console.log(JSON.stringify(tokenInfo));
console.log(
`Success! You staked ${numberFormat.format(
toDecimals(evt.data.amount, tokenInfo.decimals),
)} ${tokenInfo.symbol} to ${tokenInfo.name}`,
);
}
if (evt.name === 'ClaimEvent') {
const tokenInfo = await getTokenInfo(evt.data.stakedToken);
console.log(
`Success! You claimed ${numberFormat.format(
toDecimals(evt.data.amount, tokenInfo.decimals),
)} ${tokenInfo.symbol} from ${tokenInfo.name}`,
);
}
return Promise.resolve();
},
);

await defaultSubscription.start();
}

main();
15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,20 @@
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@dialectlabs/monitor": "^1.2.11",
"@dialectlabs/monitor": "^1.2.12",
"@dialectlabs/web3": "^0.2.0",
"@project-serum/anchor": "0.23.0",
"@gokiprotocol/client": "^0.6.1",
"@nestjs/common": "^8.0.0",
"@nestjs/core": "^8.0.0",
"@nestjs/platform-express": "^8.0.0",
"@nestjs/schedule": "^1.0.2",
"@project-serum/anchor": "0.23.0",
"@quarryprotocol/gauge": "^0.2.2",
"@quarryprotocol/quarry-sdk": "^2.0.1",
"@saberhq/anchor-contrib": "^1.12.45",
"@saberhq/solana-contrib": "^1.12.45",
"@saberhq/token-utils": "^1.12.45",
"@solana/web3.js": "^1.34.0",
"@quarryprotocol/quarry-sdk": "^5.0.2",
"@saberhq/anchor-contrib": "^1.12.61",
"@saberhq/solana-contrib": "^1.12.61",
"@saberhq/token-utils": "^1.12.61",
"@solana/web3.js": "^1.37.0",
"@tribecahq/tribeca-sdk": "^0.4.2",
"axios": "^0.26.0",
"bn.js": "^5.2.0",
Expand All @@ -51,6 +51,7 @@
"@nestjs/testing": "^8.0.0",
"@types/axios": "^0.14.0",
"@types/bn.js": "^5.1.0",
"@types/bs58": "^4.0.1",
"@types/cron": "^1.7.3",
"@types/express": "^4.17.13",
"@types/jest": "27.4.0",
Expand Down
9 changes: 8 additions & 1 deletion src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { Module } from '@nestjs/common';
import { SaberMonitoringService } from './monitor/saber-monitoring-service';
import { ScheduleModule } from '@nestjs/schedule';
import { DialectConnection } from './monitor/dialect-connection';

@Module({
imports: [ScheduleModule.forRoot()],
controllers: [],
providers: [SaberMonitoringService],
providers: [
{
provide: DialectConnection,
useValue: DialectConnection.initialize(),
},
SaberMonitoringService,
],
})
export class AppModule {}
18 changes: 18 additions & 0 deletions src/monitor/console-notification-sink.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {
Notification,
NotificationSink,
ResourceId,
} from '@dialectlabs/monitor';

export class ConsoleNotificationSink<N extends Notification>
implements NotificationSink<N>
{
push(notification: N, recipients: ResourceId[]): Promise<void> {
console.log(
`Got new notification ${JSON.stringify(
notification,
)} for recipients ${recipients}`,
);
return Promise.resolve();
}
}
57 changes: 57 additions & 0 deletions src/monitor/dialect-connection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
import { Idl, Program, Provider } from '@project-serum/anchor';
import { idl, programs, Wallet_ } from '@dialectlabs/web3';

export abstract class DialectConnection {
static initialize(): DialectConnection {
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const keypair: Keypair = Keypair.fromSecretKey(
new Uint8Array(JSON.parse(PRIVATE_KEY as string)),
);
const wallet = Wallet_.embedded(keypair.secretKey);
const RPC_URL = process.env.RPC_URL || 'http://localhost:8899';
console.log('RPC url', RPC_URL);
const dialectConnection = new Connection(RPC_URL, {
commitment: 'recent',
});
const dialectProvider = new Provider(
dialectConnection,
wallet,
Provider.defaultOptions(),
);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const NETWORK_NAME: 'devnet' | 'localnet' =
process.env.NETWORK_NAME ?? 'localnet';
console.log('Network name', NETWORK_NAME);
// const DIALECT_PROGRAM_ADDRESS = new PublicKey(
// 'BTHDR8UjttR3mX3PwT8MuEKDDzDYwqENYgPHH7QjaJ3y',
// );
const DIALECT_PROGRAM_ADDRESS = programs[NETWORK_NAME].programAddress;
const program = new Program(
idl as Idl,
new PublicKey(DIALECT_PROGRAM_ADDRESS),
dialectProvider,
);
return new DialectConnectionImpl(keypair, program);
}

abstract getKeypair(): Keypair;

abstract getProgram(): Program;
}

export class DialectConnectionImpl {
constructor(
private readonly keypair: Keypair,
private readonly program: Program,
) {}

getKeypair(): Keypair {
return this.keypair;
}

getProgram(): Program {
return this.program;
}
}
2 changes: 1 addition & 1 deletion src/monitor/noop-subscriber-repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export class NoopSubscriberRepository implements SubscriberRepository {
}

findByResourceId(): Promise<ResourceId | null> {
return null;
return Promise.resolve(null);
}

subscribe(): any {
Expand Down
Loading

0 comments on commit e6cbb52

Please sign in to comment.