@helium/distributor-oracle 0.9.29 → 0.9.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/constants.js +17 -0
- package/lib/cjs/constants.js.map +1 -0
- package/lib/cjs/database.js +9 -0
- package/lib/cjs/database.js.map +1 -0
- package/lib/cjs/model.js +19 -1
- package/lib/cjs/model.js.map +1 -1
- package/lib/cjs/pgDatabase.js +184 -0
- package/lib/cjs/pgDatabase.js.map +1 -0
- package/lib/cjs/server.js +206 -132
- package/lib/cjs/server.js.map +1 -1
- package/lib/esm/src/constants.js +14 -0
- package/lib/esm/src/constants.js.map +1 -0
- package/lib/esm/src/database.js +6 -0
- package/lib/esm/src/database.js.map +1 -0
- package/lib/esm/src/model.js +18 -1
- package/lib/esm/src/model.js.map +1 -1
- package/lib/esm/src/pgDatabase.js +169 -0
- package/lib/esm/src/pgDatabase.js.map +1 -0
- package/lib/esm/src/server.js +188 -123
- package/lib/esm/src/server.js.map +1 -1
- package/lib/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/lib/types/src/constants.d.ts +6 -0
- package/lib/types/src/constants.d.ts.map +1 -0
- package/lib/types/src/database.d.ts +32 -0
- package/lib/types/src/database.d.ts.map +1 -0
- package/lib/types/src/model.d.ts +4 -0
- package/lib/types/src/model.d.ts.map +1 -1
- package/lib/types/src/pgDatabase.d.ts +24 -0
- package/lib/types/src/pgDatabase.d.ts.map +1 -0
- package/lib/types/src/server.d.ts +9 -21
- package/lib/types/src/server.d.ts.map +1 -1
- package/package.json +12 -10
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
import { BN } from "@coral-xyz/anchor";
|
|
3
|
+
import { decodeEntityKey, entityCreatorKey, keyToAssetForAsset, } from "@helium/helium-entity-manager-sdk";
|
|
4
|
+
import { lazyDistributorKey, recipientKey } from "@helium/lazy-distributor-sdk";
|
|
5
|
+
import { getAsset, HNT_MINT, searchAssets, } from "@helium/spl-utils";
|
|
6
|
+
import { PublicKey } from "@solana/web3.js";
|
|
7
|
+
import { Op } from "sequelize";
|
|
8
|
+
import { DAO } from "./constants";
|
|
9
|
+
import { DeviceType, } from "./database";
|
|
10
|
+
import { Reward, sequelize, WalletClaimJob } from "./model";
|
|
11
|
+
const ENTITY_CREATOR = entityCreatorKey(DAO)[0];
|
|
12
|
+
const HNT_LAZY_DISTRIBUTOR = lazyDistributorKey(HNT_MINT)[0];
|
|
13
|
+
const getRewardTypeForDevice = (deviceType) => `${deviceType.toString().toLowerCase()}_gateway`;
|
|
14
|
+
export class PgDatabase {
|
|
15
|
+
issuanceProgram;
|
|
16
|
+
lazyDistributorProgram;
|
|
17
|
+
getAssetFn;
|
|
18
|
+
searchAssetsFn;
|
|
19
|
+
constructor(issuanceProgram, lazyDistributorProgram, getAssetFn = getAsset, searchAssetsFn = searchAssets) {
|
|
20
|
+
this.issuanceProgram = issuanceProgram;
|
|
21
|
+
this.lazyDistributorProgram = lazyDistributorProgram;
|
|
22
|
+
this.getAssetFn = getAssetFn;
|
|
23
|
+
this.searchAssetsFn = searchAssetsFn;
|
|
24
|
+
}
|
|
25
|
+
async getOrCreateWalletClaimJob(wallet, batchNumber) {
|
|
26
|
+
if (!batchNumber) {
|
|
27
|
+
await WalletClaimJob.destroy({
|
|
28
|
+
where: { wallet: wallet.toBase58() },
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
const job = await WalletClaimJob.findOne({
|
|
32
|
+
where: { wallet: wallet.toBase58() },
|
|
33
|
+
});
|
|
34
|
+
if (!job) {
|
|
35
|
+
let page = 1;
|
|
36
|
+
const limit = 1000;
|
|
37
|
+
let allKtas = [];
|
|
38
|
+
while (true) {
|
|
39
|
+
const assets = (await this.searchAssetsFn(process.env.ASSET_API_URL ||
|
|
40
|
+
this.issuanceProgram.provider.connection.rpcEndpoint, {
|
|
41
|
+
ownerAddress: wallet.toBase58(),
|
|
42
|
+
creatorVerified: true,
|
|
43
|
+
creatorAddress: ENTITY_CREATOR.toBase58(),
|
|
44
|
+
page,
|
|
45
|
+
limit,
|
|
46
|
+
})) || [];
|
|
47
|
+
allKtas = allKtas.concat(assets.map((asset) => keyToAssetForAsset(asset, DAO).toBase58()));
|
|
48
|
+
if (assets.length < limit) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
page++;
|
|
52
|
+
}
|
|
53
|
+
const job = await WalletClaimJob.create({
|
|
54
|
+
wallet: wallet.toBase58(),
|
|
55
|
+
remainingKtas: allKtas,
|
|
56
|
+
});
|
|
57
|
+
await job.save();
|
|
58
|
+
return job;
|
|
59
|
+
}
|
|
60
|
+
return job;
|
|
61
|
+
}
|
|
62
|
+
async getRewardableEntities(wallet, limit, batchNumber = 0) {
|
|
63
|
+
const job = await this.getOrCreateWalletClaimJob(wallet, batchNumber);
|
|
64
|
+
const entities = [];
|
|
65
|
+
let nextBatchNumber = batchNumber || 0;
|
|
66
|
+
while (entities.length == 0) {
|
|
67
|
+
const remainingKtas = job.remainingKtas.slice(nextBatchNumber * limit, (nextBatchNumber + 1) * limit);
|
|
68
|
+
if (remainingKtas.length === 0) {
|
|
69
|
+
nextBatchNumber++;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
const ktas = (await this.issuanceProgram.account.keyToAssetV0.fetchMultiple(remainingKtas)).map((kta, index) => ({
|
|
73
|
+
...kta,
|
|
74
|
+
address: new PublicKey(remainingKtas[index]),
|
|
75
|
+
}));
|
|
76
|
+
const assets = ktas.map((kta) => kta.asset);
|
|
77
|
+
const recipientKeys = assets.map((a) => recipientKey(HNT_LAZY_DISTRIBUTOR, a)[0]);
|
|
78
|
+
const recipients = (await this.lazyDistributorProgram.account.recipientV0.fetchMultiple(recipientKeys)).map((r, index) => ({
|
|
79
|
+
...r,
|
|
80
|
+
address: new PublicKey(recipientKeys[index]),
|
|
81
|
+
}));
|
|
82
|
+
const entityKeys = ktas.map((kta) => decodeEntityKey(kta.entityKey, kta.keySerialization));
|
|
83
|
+
const lifetimeRewards = await this.getBulkRewards(entityKeys);
|
|
84
|
+
for (let i = 0; i < recipients.length; i++) {
|
|
85
|
+
const entityKey = entityKeys[i];
|
|
86
|
+
const recipient = recipients[i];
|
|
87
|
+
const kta = ktas[i];
|
|
88
|
+
const lifetimeReward = lifetimeRewards[entityKey];
|
|
89
|
+
const pendingRewards = new BN(lifetimeReward).sub(recipient?.totalRewards || new BN("0"));
|
|
90
|
+
if (!pendingRewards.lte(new BN("0"))) {
|
|
91
|
+
entities.push({
|
|
92
|
+
keyToAsset: kta,
|
|
93
|
+
lifetimeReward: lifetimeReward,
|
|
94
|
+
pendingReward: pendingRewards.toString(),
|
|
95
|
+
recipient: recipient,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
nextBatchNumber++;
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
entities,
|
|
103
|
+
nextBatchNumber,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
async getTotalRewards() {
|
|
107
|
+
const totalRewards = (await Reward.findAll({
|
|
108
|
+
attributes: [
|
|
109
|
+
[sequelize.fn("SUM", sequelize.col("rewards")), "rewards"],
|
|
110
|
+
],
|
|
111
|
+
}))[0].rewards;
|
|
112
|
+
return totalRewards;
|
|
113
|
+
}
|
|
114
|
+
getActiveDevices(type) {
|
|
115
|
+
const rewardTypes = type
|
|
116
|
+
? [getRewardTypeForDevice(type)]
|
|
117
|
+
: Object.values(DeviceType)
|
|
118
|
+
.filter((value) => isNaN(Number(value))) // Filter out numeric enum keys
|
|
119
|
+
.map((deviceType) => getRewardTypeForDevice(deviceType));
|
|
120
|
+
return Reward.count({
|
|
121
|
+
where: {
|
|
122
|
+
lastReward: {
|
|
123
|
+
[Op.gte]: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30), // Active within the last 30 days
|
|
124
|
+
},
|
|
125
|
+
rewardType: {
|
|
126
|
+
[Op.in]: rewardTypes,
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
async getBulkRewards(entityKeys) {
|
|
132
|
+
const rewards = await Reward.findAll({
|
|
133
|
+
where: {
|
|
134
|
+
address: {
|
|
135
|
+
[Op.in]: entityKeys,
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
return rewards
|
|
140
|
+
.map((rew) => [rew.address, rew.rewards])
|
|
141
|
+
.reduce((acc, [key, val]) => {
|
|
142
|
+
acc[key] = new BN(val).toString();
|
|
143
|
+
return acc;
|
|
144
|
+
}, {});
|
|
145
|
+
}
|
|
146
|
+
async getCurrentRewards(assetId) {
|
|
147
|
+
const asset = await this.getAssetFn(process.env.ASSET_API_URL ||
|
|
148
|
+
this.issuanceProgram.provider.connection.rpcEndpoint, assetId);
|
|
149
|
+
if (!asset) {
|
|
150
|
+
console.error("No asset found", assetId.toBase58());
|
|
151
|
+
return "0";
|
|
152
|
+
}
|
|
153
|
+
const keyToAssetKey = keyToAssetForAsset(asset, DAO);
|
|
154
|
+
const keyToAsset = await this.issuanceProgram.account.keyToAssetV0.fetch(keyToAssetKey);
|
|
155
|
+
const entityKey = decodeEntityKey(keyToAsset.entityKey, keyToAsset.keySerialization);
|
|
156
|
+
// Verify the creator is our entity creator, otherwise they could just
|
|
157
|
+
// pass in any NFT with this ecc compact to collect rewards
|
|
158
|
+
if (!asset.creators[0].verified ||
|
|
159
|
+
!new PublicKey(asset.creators[0].address).equals(ENTITY_CREATOR)) {
|
|
160
|
+
throw new Error("Not a valid rewardable entity");
|
|
161
|
+
}
|
|
162
|
+
return this.getCurrentRewardsByEntity(entityKey);
|
|
163
|
+
}
|
|
164
|
+
async getCurrentRewardsByEntity(entityKeyStr) {
|
|
165
|
+
const reward = (await Reward.findByPk(entityKeyStr));
|
|
166
|
+
return new BN(reward?.rewards).toString() || "0";
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=pgDatabase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pgDatabase.js","sourceRoot":"","sources":["../../../src/pgDatabase.ts"],"names":[],"mappings":"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"}
|
package/lib/esm/src/server.js
CHANGED
|
@@ -1,113 +1,34 @@
|
|
|
1
|
-
import dotenv from "dotenv";
|
|
2
|
-
dotenv.config();
|
|
3
1
|
import { compileTransaction, customSignerKey, init as initTuktuk, RemoteTaskTransactionV0, } from "@helium/tuktuk-sdk";
|
|
2
|
+
import dotenv from "dotenv";
|
|
4
3
|
import { sign } from "tweetnacl";
|
|
4
|
+
dotenv.config();
|
|
5
5
|
// @ts-ignore
|
|
6
6
|
import { AnchorProvider, BN, getProvider, setProvider, } from "@coral-xyz/anchor";
|
|
7
|
-
import { decodeEntityKey, entityCreatorKey, init as initHeliumEntityManager, keyToAssetKey, keyToAssetForAsset, } from "@helium/helium-entity-manager-sdk";
|
|
8
|
-
import { daoKey } from "@helium/helium-sub-daos-sdk";
|
|
9
|
-
import { distributeCompressionRewards, init as initLazy, lazyDistributorKey, PROGRAM_ID as LD_PID, recipientKey, } from "@helium/lazy-distributor-sdk";
|
|
10
|
-
import { init as initRewards, PROGRAM_ID as RO_PID, } from "@helium/rewards-oracle-sdk";
|
|
11
|
-
import { getAsset, HNT_MINT, IOT_MINT, toNumber, } from "@helium/spl-utils";
|
|
12
|
-
import { AccountFetchCache } from "@helium/account-fetch-cache";
|
|
13
|
-
import { Keypair, PublicKey, ComputeBudgetProgram, VersionedTransaction, } from "@solana/web3.js";
|
|
14
|
-
import { Op } from "sequelize";
|
|
15
|
-
import fs from "fs";
|
|
16
|
-
import { Reward, sequelize } from "./model";
|
|
17
|
-
import Fastify from "fastify";
|
|
18
7
|
import cors from "@fastify/cors";
|
|
8
|
+
import { AccountFetchCache } from "@helium/account-fetch-cache";
|
|
9
|
+
import { decodeEntityKey, init as initHeliumEntityManager, keyToAssetKey, } from "@helium/helium-entity-manager-sdk";
|
|
10
|
+
import { init as initHplCrons } from "@helium/hpl-crons-sdk";
|
|
11
|
+
import { distributeCompressionRewards, initializeCompressionRecipient, init as initLazy, lazyDistributorKey, PROGRAM_ID as LD_PID, recipientKey, } from "@helium/lazy-distributor-sdk";
|
|
12
|
+
import { init as initRewards, PROGRAM_ID as RO_PID, } from "@helium/rewards-oracle-sdk";
|
|
13
|
+
import { getAsset, toNumber } from "@helium/spl-utils";
|
|
19
14
|
import { getLeafAssetId } from "@metaplex-foundation/mpl-bubblegum";
|
|
20
|
-
import {
|
|
15
|
+
import { createMemoInstruction } from "@solana/spl-memo";
|
|
21
16
|
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
export
|
|
31
|
-
issuanceProgram;
|
|
32
|
-
getAssetFn;
|
|
33
|
-
constructor(issuanceProgram, getAssetFn = getAsset) {
|
|
34
|
-
this.issuanceProgram = issuanceProgram;
|
|
35
|
-
this.getAssetFn = getAssetFn;
|
|
36
|
-
}
|
|
37
|
-
async getTotalRewards() {
|
|
38
|
-
const totalRewards = (await Reward.findAll({
|
|
39
|
-
attributes: [
|
|
40
|
-
[sequelize.fn("SUM", sequelize.col("rewards")), "rewards"],
|
|
41
|
-
],
|
|
42
|
-
}))[0].rewards;
|
|
43
|
-
return totalRewards;
|
|
44
|
-
}
|
|
45
|
-
getActiveDevices() {
|
|
46
|
-
return Reward.count({
|
|
47
|
-
where: {
|
|
48
|
-
[Op.and]: [
|
|
49
|
-
{
|
|
50
|
-
lastReward: {
|
|
51
|
-
[Op.gte]: new Date(Date.now() - 1000 * 60 * 60 * 24 * 30), // Active within the last 30 days
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
[Op.or]: [
|
|
56
|
-
{
|
|
57
|
-
rewardType: "mobile_gateway",
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
rewardType: "iot_gateway",
|
|
61
|
-
},
|
|
62
|
-
],
|
|
63
|
-
},
|
|
64
|
-
],
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
async getBulkRewards(entityKeys) {
|
|
69
|
-
const rewards = await Reward.findAll({
|
|
70
|
-
where: {
|
|
71
|
-
address: {
|
|
72
|
-
[Op.in]: entityKeys,
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
});
|
|
76
|
-
return rewards
|
|
77
|
-
.map((rew) => [rew.address, rew.rewards])
|
|
78
|
-
.reduce((acc, [key, val]) => {
|
|
79
|
-
acc[key] = new BN(val).toString();
|
|
80
|
-
return acc;
|
|
81
|
-
}, {});
|
|
82
|
-
}
|
|
83
|
-
async getCurrentRewards(assetId) {
|
|
84
|
-
const asset = await this.getAssetFn(process.env.ASSET_API_URL ||
|
|
85
|
-
this.issuanceProgram.provider.connection.rpcEndpoint, assetId);
|
|
86
|
-
if (!asset) {
|
|
87
|
-
console.error("No asset found", assetId.toBase58());
|
|
88
|
-
return "0";
|
|
89
|
-
}
|
|
90
|
-
const keyToAssetKey = keyToAssetForAsset(asset, DAO);
|
|
91
|
-
const keyToAsset = await this.issuanceProgram.account.keyToAssetV0.fetch(keyToAssetKey);
|
|
92
|
-
const entityKey = decodeEntityKey(keyToAsset.entityKey, keyToAsset.keySerialization);
|
|
93
|
-
// Verify the creator is our entity creator, otherwise they could just
|
|
94
|
-
// pass in any NFT with this ecc compact to collect rewards
|
|
95
|
-
if (!asset.creators[0].verified ||
|
|
96
|
-
!new PublicKey(asset.creators[0].address).equals(ENTITY_CREATOR)) {
|
|
97
|
-
throw new Error("Not a valid rewardable entity");
|
|
98
|
-
}
|
|
99
|
-
return this.getCurrentRewardsByEntity(entityKey);
|
|
100
|
-
}
|
|
101
|
-
async getCurrentRewardsByEntity(entityKeyStr) {
|
|
102
|
-
const reward = (await Reward.findByPk(entityKeyStr));
|
|
103
|
-
return new BN(reward?.rewards).toString() || "0";
|
|
104
|
-
}
|
|
105
|
-
}
|
|
17
|
+
import { ComputeBudgetProgram, Keypair, PublicKey, SystemProgram, VersionedTransaction, } from "@solana/web3.js";
|
|
18
|
+
import Fastify from "fastify";
|
|
19
|
+
import fs from "fs";
|
|
20
|
+
import { DAO, DNT, MAX_CLAIMS_PER_TX } from "./constants";
|
|
21
|
+
import { DeviceType } from "./database";
|
|
22
|
+
import { register, totalRewardsGauge } from "./metrics";
|
|
23
|
+
import { PgDatabase } from "./pgDatabase";
|
|
24
|
+
import { Reward, WalletClaimJob } from "./model";
|
|
25
|
+
export * from "./database";
|
|
106
26
|
export class OracleServer {
|
|
107
27
|
tuktukProgram;
|
|
108
28
|
ldProgram;
|
|
109
29
|
roProgram;
|
|
110
30
|
hemProgram;
|
|
31
|
+
hplCronsProgram;
|
|
111
32
|
oracle;
|
|
112
33
|
db;
|
|
113
34
|
lazyDistributor;
|
|
@@ -117,11 +38,12 @@ export class OracleServer {
|
|
|
117
38
|
server;
|
|
118
39
|
constructor(
|
|
119
40
|
// tuktuk is on a different version of anchor, so this has to be done.
|
|
120
|
-
tuktukProgram, ldProgram, roProgram, hemProgram, oracle, db, lazyDistributor, dao = DAO) {
|
|
41
|
+
tuktukProgram, ldProgram, roProgram, hemProgram, hplCronsProgram, oracle, db, lazyDistributor, dao = DAO) {
|
|
121
42
|
this.tuktukProgram = tuktukProgram;
|
|
122
43
|
this.ldProgram = ldProgram;
|
|
123
44
|
this.roProgram = roProgram;
|
|
124
45
|
this.hemProgram = hemProgram;
|
|
46
|
+
this.hplCronsProgram = hplCronsProgram;
|
|
125
47
|
this.oracle = oracle;
|
|
126
48
|
this.db = db;
|
|
127
49
|
this.lazyDistributor = lazyDistributor;
|
|
@@ -164,6 +86,8 @@ export class OracleServer {
|
|
|
164
86
|
await this.app.close();
|
|
165
87
|
}
|
|
166
88
|
addRoutes() {
|
|
89
|
+
this.app.get("/active-iot-devices", this.getActiveIotDevicesHandler.bind(this));
|
|
90
|
+
this.app.get("/active-mobile-devices", this.getActiveMobileDevicesHandler.bind(this));
|
|
167
91
|
this.app.get("/active-devices", this.getActiveDevicesHandler.bind(this));
|
|
168
92
|
this.app.post("/bulk-rewards", this.getAllRewardsHandler.bind(this));
|
|
169
93
|
this.app.get("/will-pay-recipient", (_req, res) => {
|
|
@@ -174,9 +98,22 @@ export class OracleServer {
|
|
|
174
98
|
this.app.get("/", this.getCurrentRewardsHandler.bind(this));
|
|
175
99
|
this.app.post("/", this.signTransactionHandler.bind(this));
|
|
176
100
|
this.app.post("/bulk-sign", this.signBulkTransactionsHandler.bind(this));
|
|
177
|
-
this.app.post("/v1/tuktuk/:keyToAssetKey", this.
|
|
101
|
+
this.app.post("/v1/tuktuk/kta/:keyToAssetKey", this.tuktukKtaHandler.bind(this));
|
|
102
|
+
this.app.post("/v1/tuktuk/wallet/:wallet", this.tuktukWalletHandler.bind(this));
|
|
178
103
|
this.app.post("/v1/sign/:keyToAssetKey", this.signHandler.bind(this));
|
|
179
104
|
}
|
|
105
|
+
async getActiveIotDevicesHandler(req, res) {
|
|
106
|
+
const count = await this.db.getActiveDevices(DeviceType.IOT);
|
|
107
|
+
res.send({
|
|
108
|
+
count,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
async getActiveMobileDevicesHandler(req, res) {
|
|
112
|
+
const count = await this.db.getActiveDevices(DeviceType.MOBILE);
|
|
113
|
+
res.send({
|
|
114
|
+
count,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
180
117
|
async getActiveDevicesHandler(req, res) {
|
|
181
118
|
const count = await this.db.getActiveDevices();
|
|
182
119
|
res.send({
|
|
@@ -429,22 +366,25 @@ export class OracleServer {
|
|
|
429
366
|
});
|
|
430
367
|
}
|
|
431
368
|
}
|
|
432
|
-
async
|
|
369
|
+
async tuktukKtaHandler(request, reply) {
|
|
433
370
|
const taskQueue = new PublicKey(request.body.task_queue);
|
|
434
371
|
const task = new PublicKey(request.body.task);
|
|
435
372
|
const taskQueuedAt = new BN(request.body.task_queued_at);
|
|
436
373
|
try {
|
|
374
|
+
let keyToAsset = await this.hemProgram.account.keyToAssetV0.fetch(new PublicKey(request.params.keyToAssetKey));
|
|
375
|
+
const asset = await getAsset(process.env.ASSET_API_URL ||
|
|
376
|
+
this.ldProgram.provider.connection.rpcEndpoint, keyToAsset.asset);
|
|
437
377
|
const [wallet, bump] = customSignerKey(taskQueue, [
|
|
438
|
-
Buffer.from("
|
|
378
|
+
Buffer.from("claim_payer"),
|
|
379
|
+
asset.ownership.owner.toBuffer(),
|
|
439
380
|
]);
|
|
440
381
|
const bumpBuffer = Buffer.alloc(1);
|
|
441
382
|
bumpBuffer.writeUint8(bump);
|
|
442
|
-
let keyToAsset = await this.hemProgram.account.keyToAssetV0.fetch(new PublicKey(request.params.keyToAssetKey));
|
|
443
383
|
const recipient = recipientKey(this.lazyDistributor, keyToAsset.asset)[0];
|
|
444
|
-
let recipientAcc = await this.ldProgram.account.recipientV0.
|
|
384
|
+
let recipientAcc = await this.ldProgram.account.recipientV0.fetchNullable(recipient);
|
|
445
385
|
let distributeIx;
|
|
446
|
-
if (recipientAcc
|
|
447
|
-
!recipientAcc
|
|
386
|
+
if (recipientAcc?.destination &&
|
|
387
|
+
!recipientAcc?.destination.equals(PublicKey.default)) {
|
|
448
388
|
const destination = recipientAcc.destination;
|
|
449
389
|
distributeIx = await this.ldProgram.methods
|
|
450
390
|
.distributeCustomDestinationV0()
|
|
@@ -460,7 +400,7 @@ export class OracleServer {
|
|
|
460
400
|
})
|
|
461
401
|
.instruction();
|
|
462
402
|
}
|
|
463
|
-
else {
|
|
403
|
+
else if (asset?.compression.compressed) {
|
|
464
404
|
distributeIx = await (await distributeCompressionRewards({
|
|
465
405
|
program: this.ldProgram,
|
|
466
406
|
assetId: keyToAsset.asset,
|
|
@@ -469,25 +409,148 @@ export class OracleServer {
|
|
|
469
409
|
payer: wallet,
|
|
470
410
|
})).instruction();
|
|
471
411
|
}
|
|
412
|
+
else {
|
|
413
|
+
distributeIx = await this.ldProgram.methods
|
|
414
|
+
.distributeRewardsV0()
|
|
415
|
+
.accounts({
|
|
416
|
+
common: {
|
|
417
|
+
payer: wallet,
|
|
418
|
+
recipient: recipient,
|
|
419
|
+
lazyDistributor: this.lazyDistributor,
|
|
420
|
+
rewardsMint: DNT,
|
|
421
|
+
owner: asset.ownership.owner,
|
|
422
|
+
destinationAccount: getAssociatedTokenAddressSync(DNT, asset.ownership.owner, true),
|
|
423
|
+
},
|
|
424
|
+
recipientMintAccount: getAssociatedTokenAddressSync(keyToAsset.asset, asset.ownership.owner, true),
|
|
425
|
+
})
|
|
426
|
+
.instruction();
|
|
427
|
+
}
|
|
472
428
|
const entityKey = decodeEntityKey(keyToAsset.entityKey, keyToAsset.keySerialization);
|
|
429
|
+
const instructions = [];
|
|
430
|
+
if (!recipientAcc) {
|
|
431
|
+
if (asset?.compression.compressed) {
|
|
432
|
+
instructions.push(await (await initializeCompressionRecipient({
|
|
433
|
+
program: this.ldProgram,
|
|
434
|
+
assetId: keyToAsset.asset,
|
|
435
|
+
lazyDistributor: this.lazyDistributor,
|
|
436
|
+
owner: wallet,
|
|
437
|
+
// Temporarily set oracle as the payer to subsidize new HNT wallets.
|
|
438
|
+
payer: wallet,
|
|
439
|
+
})).instruction());
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
instructions.push(await this.ldProgram.methods
|
|
443
|
+
.initializeRecipientV0()
|
|
444
|
+
.accounts({
|
|
445
|
+
recipient: recipient,
|
|
446
|
+
lazyDistributor: this.lazyDistributor,
|
|
447
|
+
payer: wallet,
|
|
448
|
+
mint: keyToAsset.asset,
|
|
449
|
+
})
|
|
450
|
+
.instruction());
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
instructions.push(await this.roProgram.methods
|
|
454
|
+
.setCurrentRewardsWrapperV2({
|
|
455
|
+
currentRewards: new BN(await this.db.getCurrentRewardsByEntity(entityKey)),
|
|
456
|
+
oracleIndex: process.env.ORACLE_INDEX
|
|
457
|
+
? parseInt(process.env.ORACLE_INDEX)
|
|
458
|
+
: 0,
|
|
459
|
+
})
|
|
460
|
+
.accounts({
|
|
461
|
+
lazyDistributor: this.lazyDistributor,
|
|
462
|
+
recipient,
|
|
463
|
+
payer: wallet,
|
|
464
|
+
keyToAsset: new PublicKey(request.params.keyToAssetKey),
|
|
465
|
+
})
|
|
466
|
+
.instruction());
|
|
467
|
+
instructions.push(distributeIx);
|
|
468
|
+
const { transaction, remainingAccounts } = await compileTransaction(instructions, [
|
|
469
|
+
[
|
|
470
|
+
Buffer.from("claim_payer"),
|
|
471
|
+
asset.ownership.owner.toBuffer(),
|
|
472
|
+
bumpBuffer,
|
|
473
|
+
],
|
|
474
|
+
]);
|
|
475
|
+
const remoteTx = new RemoteTaskTransactionV0({
|
|
476
|
+
task,
|
|
477
|
+
taskQueuedAt,
|
|
478
|
+
transaction: {
|
|
479
|
+
...transaction,
|
|
480
|
+
accounts: remainingAccounts.map((acc) => acc.pubkey),
|
|
481
|
+
},
|
|
482
|
+
});
|
|
483
|
+
const serialized = await RemoteTaskTransactionV0.serialize(this.tuktukProgram.coder.accounts, remoteTx);
|
|
484
|
+
const resp = {
|
|
485
|
+
transaction: serialized.toString("base64"),
|
|
486
|
+
signature: Buffer.from(sign.detached(Uint8Array.from(serialized), this.oracle.secretKey)).toString("base64"),
|
|
487
|
+
remaining_accounts: remainingAccounts.map((acc) => ({
|
|
488
|
+
pubkey: acc.pubkey.toBase58(),
|
|
489
|
+
is_signer: acc.isSigner,
|
|
490
|
+
is_writable: acc.isWritable,
|
|
491
|
+
})),
|
|
492
|
+
};
|
|
493
|
+
reply.status(200).send(resp);
|
|
494
|
+
}
|
|
495
|
+
catch (err) {
|
|
496
|
+
console.error(err);
|
|
497
|
+
reply.status(500).send({
|
|
498
|
+
message: "Request failed",
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
async tuktukWalletHandler(request, reply) {
|
|
503
|
+
const wallet = request.params.wallet;
|
|
504
|
+
const batchNumber = request.query.batchNumber;
|
|
505
|
+
const taskQueue = new PublicKey(request.body.task_queue);
|
|
506
|
+
const task = new PublicKey(request.body.task);
|
|
507
|
+
const taskQueuedAt = new BN(request.body.task_queued_at);
|
|
508
|
+
try {
|
|
509
|
+
const [customSignerWallet, bump] = customSignerKey(taskQueue, [
|
|
510
|
+
Buffer.from("claim_payer"),
|
|
511
|
+
new PublicKey(wallet).toBuffer(),
|
|
512
|
+
]);
|
|
513
|
+
const bumpBuffer = Buffer.alloc(1);
|
|
514
|
+
bumpBuffer.writeUint8(bump);
|
|
515
|
+
const { entities, nextBatchNumber } = await this.db.getRewardableEntities(new PublicKey(wallet), MAX_CLAIMS_PER_TX, Number(batchNumber || 0));
|
|
516
|
+
const taskQueueAcc = await this.tuktukProgram.account.taskQueueV0.fetch(taskQueue);
|
|
473
517
|
const instructions = [
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
518
|
+
SystemProgram.transfer({
|
|
519
|
+
fromPubkey: customSignerWallet,
|
|
520
|
+
toPubkey: task,
|
|
521
|
+
lamports: taskQueueAcc.minCrankReward.toNumber() * (entities.length + 1),
|
|
522
|
+
}),
|
|
523
|
+
];
|
|
524
|
+
for (const entity of entities) {
|
|
525
|
+
instructions.push(await this.hplCronsProgram.methods
|
|
526
|
+
.requeueEntityClaimV0()
|
|
527
|
+
.accounts({
|
|
528
|
+
keyToAsset: entity.keyToAsset.address,
|
|
529
|
+
})
|
|
530
|
+
.instruction());
|
|
531
|
+
}
|
|
532
|
+
if (entities.length > 0) {
|
|
533
|
+
instructions.push(await this.hplCronsProgram.methods
|
|
534
|
+
.requeueWalletClaimV0({
|
|
535
|
+
batchNumber: nextBatchNumber,
|
|
480
536
|
})
|
|
481
537
|
.accounts({
|
|
482
|
-
|
|
483
|
-
recipient,
|
|
484
|
-
payer: wallet,
|
|
485
|
-
keyToAsset: new PublicKey(request.params.keyToAssetKey),
|
|
538
|
+
wallet: new PublicKey(wallet),
|
|
486
539
|
})
|
|
487
|
-
.instruction()
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
540
|
+
.instruction());
|
|
541
|
+
}
|
|
542
|
+
else {
|
|
543
|
+
instructions.push(createMemoInstruction("Finished claiming rewards", [
|
|
544
|
+
customSignerWallet,
|
|
545
|
+
]));
|
|
546
|
+
}
|
|
547
|
+
const { transaction, remainingAccounts } = await compileTransaction(instructions, [
|
|
548
|
+
[
|
|
549
|
+
Buffer.from("claim_payer"),
|
|
550
|
+
new PublicKey(wallet).toBuffer(),
|
|
551
|
+
bumpBuffer,
|
|
552
|
+
],
|
|
553
|
+
]);
|
|
491
554
|
const remoteTx = new RemoteTaskTransactionV0({
|
|
492
555
|
task,
|
|
493
556
|
taskQueuedAt,
|
|
@@ -506,7 +569,6 @@ export class OracleServer {
|
|
|
506
569
|
is_writable: acc.isWritable,
|
|
507
570
|
})),
|
|
508
571
|
};
|
|
509
|
-
console.log(resp);
|
|
510
572
|
reply.status(200).send(resp);
|
|
511
573
|
}
|
|
512
574
|
catch (err) {
|
|
@@ -572,8 +634,11 @@ export class OracleServer {
|
|
|
572
634
|
const ldProgram = await initLazy(provider);
|
|
573
635
|
const roProgram = await initRewards(provider);
|
|
574
636
|
const hemProgram = await initHeliumEntityManager(provider);
|
|
637
|
+
const hplCronsProgram = await initHplCrons(provider);
|
|
638
|
+
WalletClaimJob.sync();
|
|
639
|
+
Reward.sync();
|
|
575
640
|
const LAZY_DISTRIBUTOR = lazyDistributorKey(DNT)[0];
|
|
576
|
-
const server = new OracleServer(tuktukProgram, ldProgram, roProgram, hemProgram, oracleKeypair, new PgDatabase(hemProgram), LAZY_DISTRIBUTOR);
|
|
641
|
+
const server = new OracleServer(tuktukProgram, ldProgram, roProgram, hemProgram, hplCronsProgram, oracleKeypair, new PgDatabase(hemProgram, ldProgram), LAZY_DISTRIBUTOR);
|
|
577
642
|
// For performance
|
|
578
643
|
new AccountFetchCache({
|
|
579
644
|
connection: provider.connection,
|