hive-stream 2.0.6 → 3.0.1
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/.claude/settings.local.json +12 -0
- package/.env.example +2 -2
- package/.travis.yml +11 -11
- package/AGENTS.md +35 -0
- package/CHANGELOG.md +166 -0
- package/CLAUDE.md +75 -0
- package/DOCUMENTATION.md +380 -0
- package/LICENSE +21 -21
- package/README.md +429 -238
- package/dist/actions.d.ts +41 -10
- package/dist/actions.js +126 -23
- package/dist/actions.js.map +1 -1
- package/dist/adapters/base.adapter.d.ts +43 -25
- package/dist/adapters/base.adapter.js +79 -49
- package/dist/adapters/base.adapter.js.map +1 -1
- package/dist/adapters/mongodb.adapter.d.ts +44 -37
- package/dist/adapters/mongodb.adapter.js +363 -158
- package/dist/adapters/mongodb.adapter.js.map +1 -1
- package/dist/adapters/postgresql.adapter.d.ts +66 -0
- package/dist/adapters/postgresql.adapter.js +598 -0
- package/dist/adapters/postgresql.adapter.js.map +1 -0
- package/dist/adapters/sqlite.adapter.d.ts +57 -41
- package/dist/adapters/sqlite.adapter.js +561 -397
- package/dist/adapters/sqlite.adapter.js.map +1 -1
- package/dist/api.d.ts +6 -6
- package/dist/api.js +181 -55
- package/dist/api.js.map +1 -1
- package/dist/config.d.ts +19 -16
- package/dist/config.js +21 -18
- package/dist/config.js.map +1 -1
- package/dist/contracts/coinflip.contract.d.ts +9 -14
- package/dist/contracts/coinflip.contract.js +232 -94
- package/dist/contracts/coinflip.contract.js.map +1 -1
- package/dist/contracts/contract.d.ts +3 -0
- package/dist/contracts/contract.js +26 -0
- package/dist/contracts/contract.js.map +1 -0
- package/dist/contracts/dice.contract.d.ts +10 -29
- package/dist/contracts/dice.contract.js +217 -155
- package/dist/contracts/dice.contract.js.map +1 -1
- package/dist/contracts/exchange.contract.d.ts +11 -0
- package/dist/contracts/exchange.contract.js +492 -0
- package/dist/contracts/exchange.contract.js.map +1 -0
- package/dist/contracts/lotto.contract.d.ts +16 -20
- package/dist/contracts/lotto.contract.js +238 -246
- package/dist/contracts/lotto.contract.js.map +1 -1
- package/dist/contracts/nft.contract.d.ts +28 -0
- package/dist/contracts/nft.contract.js +598 -0
- package/dist/contracts/nft.contract.js.map +1 -0
- package/dist/contracts/poll.contract.d.ts +4 -0
- package/dist/contracts/poll.contract.js +105 -0
- package/dist/contracts/poll.contract.js.map +1 -0
- package/dist/contracts/rps.contract.d.ts +9 -0
- package/dist/contracts/rps.contract.js +217 -0
- package/dist/contracts/rps.contract.js.map +1 -0
- package/dist/contracts/tipjar.contract.d.ts +4 -0
- package/dist/contracts/tipjar.contract.js +60 -0
- package/dist/contracts/tipjar.contract.js.map +1 -0
- package/dist/contracts/token.contract.d.ts +4 -0
- package/dist/contracts/token.contract.js +311 -0
- package/dist/contracts/token.contract.js.map +1 -0
- package/dist/exchanges/bittrex.d.ts +6 -6
- package/dist/exchanges/bittrex.js +34 -34
- package/dist/exchanges/coingecko.d.ts +11 -0
- package/dist/exchanges/coingecko.js +57 -0
- package/dist/exchanges/coingecko.js.map +1 -0
- package/dist/exchanges/exchange.d.ts +16 -9
- package/dist/exchanges/exchange.js +80 -26
- package/dist/exchanges/exchange.js.map +1 -1
- package/dist/hive-rates.d.ts +34 -9
- package/dist/hive-rates.js +208 -75
- package/dist/hive-rates.js.map +1 -1
- package/dist/index.d.ts +19 -11
- package/dist/index.js +47 -32
- package/dist/index.js.map +1 -1
- package/dist/streamer.d.ts +233 -93
- package/dist/streamer.js +1063 -545
- package/dist/streamer.js.map +1 -1
- package/dist/test.d.ts +1 -1
- package/dist/test.js +24 -25
- package/dist/test.js.map +1 -1
- package/dist/types/hive-stream.d.ts +106 -6
- package/dist/types/hive-stream.js +2 -2
- package/dist/types/rates.d.ts +47 -0
- package/dist/types/rates.js +29 -0
- package/dist/types/rates.js.map +1 -0
- package/dist/utils.d.ts +334 -27
- package/dist/utils.js +960 -261
- package/dist/utils.js.map +1 -1
- package/ecosystem.config.js +17 -17
- package/examples/contracts/README.md +8 -0
- package/examples/contracts/exchange.ts +38 -0
- package/examples/contracts/poll.ts +21 -0
- package/examples/contracts/rps.ts +19 -0
- package/examples/contracts/tipjar.ts +19 -0
- package/jest.config.js +8 -8
- package/package.json +54 -48
- package/test-contract-block.md +18 -18
- package/tests/actions.spec.ts +252 -0
- package/tests/adapters/actions-persistence.spec.ts +144 -0
- package/tests/adapters/postgresql.adapter.spec.ts +127 -0
- package/tests/adapters/sqlite.adapter.spec.ts +180 -42
- package/tests/contracts/coinflip.contract.spec.ts +94 -132
- package/tests/contracts/dice.contract.spec.ts +87 -160
- package/tests/contracts/entrants.json +728 -728
- package/tests/contracts/exchange.contract.spec.ts +84 -0
- package/tests/contracts/lotto.contract.spec.ts +59 -324
- package/tests/contracts/nft.contract.spec.ts +948 -0
- package/tests/contracts/token.contract.spec.ts +90 -0
- package/tests/exchanges/coingecko.exchange.spec.ts +169 -0
- package/tests/exchanges/exchange.base.spec.ts +246 -0
- package/tests/helpers/mock-adapter.ts +214 -0
- package/tests/helpers/mock-fetch.ts +165 -0
- package/tests/hive-chain-features.spec.ts +238 -0
- package/tests/hive-rates.spec.ts +443 -0
- package/tests/integration/hive-rates.integration.spec.ts +35 -0
- package/tests/setup.ts +29 -18
- package/tests/streamer-actions.spec.ts +274 -0
- package/tests/streamer.spec.ts +342 -152
- package/tests/types/rates.spec.ts +216 -0
- package/tests/utils.spec.ts +113 -95
- package/tsconfig.build.json +3 -22
- package/tslint.json +20 -20
- package/wallaby.js +26 -26
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createPollContract = createPollContract;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const contract_1 = require("./contract");
|
|
6
|
+
const DEFAULT_NAME = 'polls';
|
|
7
|
+
function createPollContract(options = {}) {
|
|
8
|
+
const name = options.name || DEFAULT_NAME;
|
|
9
|
+
const state = {
|
|
10
|
+
adapter: null
|
|
11
|
+
};
|
|
12
|
+
const createPollSchema = zod_1.z.object({
|
|
13
|
+
pollId: zod_1.z.string().min(1).max(64),
|
|
14
|
+
question: zod_1.z.string().min(3).max(280),
|
|
15
|
+
options: zod_1.z.array(zod_1.z.string().min(1).max(100)).min(2).max(10),
|
|
16
|
+
durationHours: zod_1.z.number().int().min(1).max(720).optional()
|
|
17
|
+
});
|
|
18
|
+
const voteSchema = zod_1.z.object({
|
|
19
|
+
pollId: zod_1.z.string().min(1).max(64),
|
|
20
|
+
option: zod_1.z.number().int().min(0)
|
|
21
|
+
});
|
|
22
|
+
const initializeTables = async () => {
|
|
23
|
+
await state.adapter.query(`
|
|
24
|
+
CREATE TABLE IF NOT EXISTS polls (
|
|
25
|
+
poll_id TEXT PRIMARY KEY,
|
|
26
|
+
question TEXT NOT NULL,
|
|
27
|
+
options TEXT NOT NULL,
|
|
28
|
+
creator TEXT NOT NULL,
|
|
29
|
+
created_at DATETIME NOT NULL,
|
|
30
|
+
closes_at DATETIME
|
|
31
|
+
)
|
|
32
|
+
`);
|
|
33
|
+
await state.adapter.query(`
|
|
34
|
+
CREATE TABLE IF NOT EXISTS poll_votes (
|
|
35
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
36
|
+
poll_id TEXT NOT NULL,
|
|
37
|
+
voter TEXT NOT NULL,
|
|
38
|
+
option_index INTEGER NOT NULL,
|
|
39
|
+
created_at DATETIME NOT NULL,
|
|
40
|
+
UNIQUE(poll_id, voter)
|
|
41
|
+
)
|
|
42
|
+
`);
|
|
43
|
+
};
|
|
44
|
+
const createPoll = async (payload, ctx) => {
|
|
45
|
+
const closesAt = payload.durationHours
|
|
46
|
+
? new Date(Date.now() + payload.durationHours * 60 * 60 * 1000)
|
|
47
|
+
: null;
|
|
48
|
+
const existing = await state.adapter.query('SELECT poll_id FROM polls WHERE poll_id = ?', [payload.pollId]);
|
|
49
|
+
if (existing && existing.length > 0) {
|
|
50
|
+
throw new Error(`Poll ${payload.pollId} already exists`);
|
|
51
|
+
}
|
|
52
|
+
await state.adapter.query('INSERT INTO polls (poll_id, question, options, creator, created_at, closes_at) VALUES (?, ?, ?, ?, ?, ?)', [payload.pollId, payload.question, JSON.stringify(payload.options), ctx.sender, new Date(), closesAt]);
|
|
53
|
+
await state.adapter.addEvent(new Date(), name, 'createPoll', payload, {
|
|
54
|
+
action: 'poll_created',
|
|
55
|
+
data: {
|
|
56
|
+
pollId: payload.pollId,
|
|
57
|
+
creator: ctx.sender,
|
|
58
|
+
closesAt
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
const vote = async (payload, ctx) => {
|
|
63
|
+
const poll = await state.adapter.query('SELECT * FROM polls WHERE poll_id = ?', [payload.pollId]);
|
|
64
|
+
if (!poll || poll.length === 0) {
|
|
65
|
+
throw new Error(`Poll ${payload.pollId} does not exist`);
|
|
66
|
+
}
|
|
67
|
+
const pollData = poll[0];
|
|
68
|
+
const options = JSON.parse(pollData.options || '[]');
|
|
69
|
+
if (payload.option < 0 || payload.option >= options.length) {
|
|
70
|
+
throw new Error('Invalid poll option');
|
|
71
|
+
}
|
|
72
|
+
if (pollData.closes_at && new Date(pollData.closes_at) < new Date()) {
|
|
73
|
+
throw new Error('Poll is closed');
|
|
74
|
+
}
|
|
75
|
+
await state.adapter.query('INSERT INTO poll_votes (poll_id, voter, option_index, created_at) VALUES (?, ?, ?, ?)', [payload.pollId, ctx.sender, payload.option, new Date()]);
|
|
76
|
+
await state.adapter.addEvent(new Date(), name, 'vote', payload, {
|
|
77
|
+
action: 'poll_voted',
|
|
78
|
+
data: {
|
|
79
|
+
pollId: payload.pollId,
|
|
80
|
+
voter: ctx.sender,
|
|
81
|
+
option: payload.option
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
return (0, contract_1.defineContract)({
|
|
86
|
+
name,
|
|
87
|
+
hooks: {
|
|
88
|
+
create: async ({ adapter }) => {
|
|
89
|
+
state.adapter = adapter;
|
|
90
|
+
await initializeTables();
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
actions: {
|
|
94
|
+
createPoll: (0, contract_1.action)(createPoll, {
|
|
95
|
+
schema: createPollSchema,
|
|
96
|
+
trigger: 'custom_json'
|
|
97
|
+
}),
|
|
98
|
+
vote: (0, contract_1.action)(vote, {
|
|
99
|
+
schema: voteSchema,
|
|
100
|
+
trigger: 'custom_json'
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=poll.contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poll.contract.js","sourceRoot":"","sources":["../../src/contracts/poll.contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface RpsContractOptions {
|
|
2
|
+
name?: string;
|
|
3
|
+
account?: string;
|
|
4
|
+
tokenSymbol?: string;
|
|
5
|
+
validCurrencies?: string[];
|
|
6
|
+
minAmount?: number;
|
|
7
|
+
maxAmount?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function createRpsContract(options?: RpsContractOptions): import("..").ContractDefinition;
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createRpsContract = createRpsContract;
|
|
7
|
+
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
8
|
+
const seedrandom_1 = __importDefault(require("seedrandom"));
|
|
9
|
+
const uuid_1 = require("uuid");
|
|
10
|
+
const zod_1 = require("zod");
|
|
11
|
+
const contract_1 = require("./contract");
|
|
12
|
+
const DEFAULT_NAME = 'rps';
|
|
13
|
+
const DEFAULT_ACCOUNT = 'beggars';
|
|
14
|
+
const DEFAULT_TOKEN_SYMBOL = 'HIVE';
|
|
15
|
+
const DEFAULT_MIN_AMOUNT = 0.001;
|
|
16
|
+
const DEFAULT_MAX_AMOUNT = 20;
|
|
17
|
+
const MOVES = ['rock', 'paper', 'scissors'];
|
|
18
|
+
function rng(previousBlockId, blockId, transactionId, serverSeed, clientSeed = '') {
|
|
19
|
+
if (!previousBlockId || !blockId || !transactionId || !serverSeed) {
|
|
20
|
+
throw new Error('Invalid RNG parameters');
|
|
21
|
+
}
|
|
22
|
+
const random = (0, seedrandom_1.default)(`${previousBlockId}${blockId}${transactionId}${clientSeed}${serverSeed}`).double();
|
|
23
|
+
const randomRoll = Math.floor(random * 3);
|
|
24
|
+
return MOVES[randomRoll];
|
|
25
|
+
}
|
|
26
|
+
function createRpsContract(options = {}) {
|
|
27
|
+
const name = options.name || DEFAULT_NAME;
|
|
28
|
+
const account = options.account || DEFAULT_ACCOUNT;
|
|
29
|
+
const tokenSymbol = options.tokenSymbol || DEFAULT_TOKEN_SYMBOL;
|
|
30
|
+
const validCurrencies = options.validCurrencies || [tokenSymbol];
|
|
31
|
+
const minAmount = options.minAmount ?? DEFAULT_MIN_AMOUNT;
|
|
32
|
+
const maxAmount = options.maxAmount ?? DEFAULT_MAX_AMOUNT;
|
|
33
|
+
const state = {
|
|
34
|
+
streamer: null,
|
|
35
|
+
adapter: null,
|
|
36
|
+
balanceCache: null,
|
|
37
|
+
balanceCacheTimeout: 30000,
|
|
38
|
+
betQueue: [],
|
|
39
|
+
processingQueue: false,
|
|
40
|
+
pendingPayouts: new bignumber_js_1.default(0)
|
|
41
|
+
};
|
|
42
|
+
const playSchema = zod_1.z.object({
|
|
43
|
+
move: zod_1.z.enum(MOVES),
|
|
44
|
+
seed: zod_1.z.string().optional()
|
|
45
|
+
});
|
|
46
|
+
const getBalance = async () => {
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
if (state.balanceCache && (now - state.balanceCache.timestamp) < state.balanceCacheTimeout) {
|
|
49
|
+
return state.balanceCache.balance;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const accountInfo = await state.streamer['client'].database.getAccounts([account]);
|
|
53
|
+
if (accountInfo?.[0]) {
|
|
54
|
+
const balanceParts = accountInfo[0].balance.split(' ');
|
|
55
|
+
const amount = new bignumber_js_1.default(balanceParts[0]);
|
|
56
|
+
if (amount.isNaN() || !amount.isFinite()) {
|
|
57
|
+
throw new Error('Invalid balance format received from API');
|
|
58
|
+
}
|
|
59
|
+
state.balanceCache = {
|
|
60
|
+
balance: amount,
|
|
61
|
+
timestamp: now
|
|
62
|
+
};
|
|
63
|
+
return amount;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error('[RpsContract] Error fetching balance:', error);
|
|
68
|
+
if (state.balanceCache) {
|
|
69
|
+
return state.balanceCache.balance;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return new bignumber_js_1.default(0);
|
|
73
|
+
};
|
|
74
|
+
const processQueue = async () => {
|
|
75
|
+
if (state.processingQueue || state.betQueue.length === 0) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
state.processingQueue = true;
|
|
79
|
+
while (state.betQueue.length > 0) {
|
|
80
|
+
const nextBet = state.betQueue.shift();
|
|
81
|
+
if (nextBet) {
|
|
82
|
+
try {
|
|
83
|
+
await nextBet();
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.error('[RpsContract] Queue processing error:', error);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
state.processingQueue = false;
|
|
91
|
+
};
|
|
92
|
+
const beats = (player, opponent) => {
|
|
93
|
+
return ((player === 'rock' && opponent === 'scissors') ||
|
|
94
|
+
(player === 'scissors' && opponent === 'paper') ||
|
|
95
|
+
(player === 'paper' && opponent === 'rock'));
|
|
96
|
+
};
|
|
97
|
+
const processPlay = async (payload, ctx) => {
|
|
98
|
+
if (!ctx.transfer) {
|
|
99
|
+
throw new Error('Transfer context required for play');
|
|
100
|
+
}
|
|
101
|
+
const sender = ctx.sender;
|
|
102
|
+
const amountRaw = ctx.transfer.rawAmount;
|
|
103
|
+
try {
|
|
104
|
+
if (!amountRaw || typeof amountRaw !== 'string' || !amountRaw.includes(' ')) {
|
|
105
|
+
throw new Error('Invalid amount format');
|
|
106
|
+
}
|
|
107
|
+
const amountTrim = amountRaw.split(' ');
|
|
108
|
+
if (amountTrim.length !== 2) {
|
|
109
|
+
throw new Error('Invalid amount format');
|
|
110
|
+
}
|
|
111
|
+
const amountParsed = new bignumber_js_1.default(amountTrim[0]);
|
|
112
|
+
if (amountParsed.isNaN() || !amountParsed.isFinite() || amountParsed.isNegative()) {
|
|
113
|
+
throw new Error('Invalid amount value');
|
|
114
|
+
}
|
|
115
|
+
const amountCurrency = amountTrim[1].trim();
|
|
116
|
+
const transaction = await state.streamer.getTransaction(ctx.block.number, ctx.transaction.id);
|
|
117
|
+
const verify = await state.streamer.verifyTransfer(transaction, sender, account, amountRaw);
|
|
118
|
+
const balance = await getBalance();
|
|
119
|
+
const availableBalance = balance.minus(state.pendingPayouts);
|
|
120
|
+
if (verify) {
|
|
121
|
+
if (!validCurrencies.includes(amountCurrency)) {
|
|
122
|
+
await state.streamer.transferHiveTokens(account, sender, amountTrim[0], amountTrim[1], '[Refund] You sent an invalid currency.');
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (amountParsed.isLessThan(minAmount)) {
|
|
126
|
+
await state.streamer.transferHiveTokens(account, sender, amountTrim[0], amountTrim[1], `[Refund] Bet amount too small. Minimum: ${minAmount} ${amountCurrency}.`);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (amountParsed.isGreaterThan(maxAmount)) {
|
|
130
|
+
await state.streamer.transferHiveTokens(account, sender, amountTrim[0], amountTrim[1], `[Refund] You sent too much. Maximum: ${maxAmount} ${amountCurrency}.`);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const potentialPayout = amountParsed.multipliedBy(2);
|
|
134
|
+
if (potentialPayout.isGreaterThan(availableBalance)) {
|
|
135
|
+
await state.streamer.transferHiveTokens(account, sender, amountTrim[0], amountTrim[1], '[Refund] The server cannot afford this bet payout.');
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
state.pendingPayouts = state.pendingPayouts.plus(potentialPayout);
|
|
139
|
+
try {
|
|
140
|
+
const serverSeed = (0, uuid_1.v4)();
|
|
141
|
+
const serverMove = rng(ctx.block.previousId, ctx.block.id, ctx.transaction.id, serverSeed, payload.seed ?? '');
|
|
142
|
+
let result = 'lose';
|
|
143
|
+
if (serverMove === payload.move) {
|
|
144
|
+
result = 'tie';
|
|
145
|
+
}
|
|
146
|
+
else if (beats(payload.move, serverMove)) {
|
|
147
|
+
result = 'win';
|
|
148
|
+
}
|
|
149
|
+
await state.adapter.addEvent(new Date(), name, 'play', payload, {
|
|
150
|
+
action: 'rps_result',
|
|
151
|
+
data: {
|
|
152
|
+
player: sender,
|
|
153
|
+
playerMove: payload.move,
|
|
154
|
+
serverMove,
|
|
155
|
+
serverSeed,
|
|
156
|
+
result,
|
|
157
|
+
blockId: ctx.block.id,
|
|
158
|
+
transactionId: ctx.transaction.id
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
if (result === 'win') {
|
|
162
|
+
await state.streamer.transferHiveTokens(account, sender, potentialPayout.toFixed(3), amountTrim[1], `[Winner] | You: ${payload.move} | Server: ${serverMove} | Seed: ${serverSeed}`);
|
|
163
|
+
}
|
|
164
|
+
else if (result === 'tie') {
|
|
165
|
+
await state.streamer.transferHiveTokens(account, sender, amountTrim[0], amountTrim[1], `[Tie] | You: ${payload.move} | Server: ${serverMove} | Seed: ${serverSeed}`);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
await state.streamer.transferHiveTokens(account, sender, '0.001', amountTrim[1], `[Lost] | You: ${payload.move} | Server: ${serverMove} | Seed: ${serverSeed}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
finally {
|
|
172
|
+
state.pendingPayouts = state.pendingPayouts.minus(potentialPayout);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
catch (e) {
|
|
177
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
178
|
+
console.error('[RpsContract] Play processing error:', {
|
|
179
|
+
sender,
|
|
180
|
+
amount: amountRaw,
|
|
181
|
+
payload,
|
|
182
|
+
message: error.message
|
|
183
|
+
});
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const play = async (payload, ctx) => {
|
|
188
|
+
return new Promise((resolve, reject) => {
|
|
189
|
+
state.betQueue.push(async () => {
|
|
190
|
+
try {
|
|
191
|
+
await processPlay(payload, ctx);
|
|
192
|
+
resolve();
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
reject(error);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
processQueue();
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
return (0, contract_1.defineContract)({
|
|
202
|
+
name,
|
|
203
|
+
hooks: {
|
|
204
|
+
create: ({ streamer, adapter }) => {
|
|
205
|
+
state.streamer = streamer;
|
|
206
|
+
state.adapter = adapter;
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
actions: {
|
|
210
|
+
play: (0, contract_1.action)(play, {
|
|
211
|
+
schema: playSchema,
|
|
212
|
+
trigger: 'transfer'
|
|
213
|
+
})
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=rps.contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rps.contract.js","sourceRoot":"","sources":["../../src/contracts/rps.contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createTipJarContract = createTipJarContract;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const contract_1 = require("./contract");
|
|
6
|
+
const DEFAULT_NAME = 'tipjar';
|
|
7
|
+
function createTipJarContract(options = {}) {
|
|
8
|
+
const name = options.name || DEFAULT_NAME;
|
|
9
|
+
const state = {
|
|
10
|
+
adapter: null
|
|
11
|
+
};
|
|
12
|
+
const tipSchema = zod_1.z.object({
|
|
13
|
+
message: zod_1.z.string().max(280).optional()
|
|
14
|
+
});
|
|
15
|
+
const initializeTables = async () => {
|
|
16
|
+
await state.adapter.query(`
|
|
17
|
+
CREATE TABLE IF NOT EXISTS tipjar_tips (
|
|
18
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
19
|
+
from_account TEXT NOT NULL,
|
|
20
|
+
amount TEXT NOT NULL,
|
|
21
|
+
asset TEXT NOT NULL,
|
|
22
|
+
message TEXT,
|
|
23
|
+
block_number INTEGER NOT NULL,
|
|
24
|
+
transaction_id TEXT NOT NULL,
|
|
25
|
+
created_at DATETIME NOT NULL
|
|
26
|
+
)
|
|
27
|
+
`);
|
|
28
|
+
};
|
|
29
|
+
const tip = async (payload, ctx) => {
|
|
30
|
+
if (!ctx.transfer) {
|
|
31
|
+
throw new Error('Transfer context required for tips');
|
|
32
|
+
}
|
|
33
|
+
await state.adapter.query('INSERT INTO tipjar_tips (from_account, amount, asset, message, block_number, transaction_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)', [ctx.sender, ctx.transfer.amount, ctx.transfer.asset, payload.message || '', ctx.block.number, ctx.transaction.id, new Date()]);
|
|
34
|
+
await state.adapter.addEvent(new Date(), name, 'tip', payload, {
|
|
35
|
+
action: 'tip_received',
|
|
36
|
+
data: {
|
|
37
|
+
from: ctx.sender,
|
|
38
|
+
amount: ctx.transfer.amount,
|
|
39
|
+
asset: ctx.transfer.asset,
|
|
40
|
+
message: payload.message || ''
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
return (0, contract_1.defineContract)({
|
|
45
|
+
name,
|
|
46
|
+
hooks: {
|
|
47
|
+
create: async ({ adapter }) => {
|
|
48
|
+
state.adapter = adapter;
|
|
49
|
+
await initializeTables();
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
actions: {
|
|
53
|
+
tip: (0, contract_1.action)(tip, {
|
|
54
|
+
schema: tipSchema,
|
|
55
|
+
trigger: 'transfer'
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=tipjar.contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tipjar.contract.js","sourceRoot":"","sources":["../../src/contracts/tipjar.contract.ts"],"names":[],"mappings":";;AASA,oDA8DC;AAvED,6BAAwB;AACxB,yCAAoD;AAEpD,MAAM,YAAY,GAAG,QAAQ,CAAC;AAM9B,SAAgB,oBAAoB,CAAC,UAAiC,EAAE;IACpE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,YAAY,CAAC;IAE1C,MAAM,KAAK,GAAG;QACV,OAAO,EAAE,IAAW;KACvB,CAAC;IAEF,MAAM,SAAS,GAAG,OAAC,CAAC,MAAM,CAAC;QACvB,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;KAC1C,CAAC,CAAC;IAEH,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;QAChC,MAAM,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;;;;;;;;;;;SAWzB,CAAC,CAAC;IACP,CAAC,CAAC;IAEF,MAAM,GAAG,GAAG,KAAK,EAAE,OAA6B,EAAE,GAAQ,EAAE,EAAE;QAC1D,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,KAAK,CAAC,OAAO,CAAC,KAAK,CACrB,uIAAuI,EACvI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,WAAW,CAAC,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,CACjI,CAAC;QAEF,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE;YAC3D,MAAM,EAAE,cAAc;YACtB,IAAI,EAAE;gBACF,IAAI,EAAE,GAAG,CAAC,MAAM;gBAChB,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM;gBAC3B,KAAK,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK;gBACzB,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;aACjC;SACJ,CAAC,CAAC;IACP,CAAC,CAAC;IAEF,OAAO,IAAA,yBAAc,EAAC;QAClB,IAAI;QACJ,KAAK,EAAE;YACH,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBAC1B,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;gBACxB,MAAM,gBAAgB,EAAE,CAAC;YAC7B,CAAC;SACJ;QACD,OAAO,EAAE;YACL,GAAG,EAAE,IAAA,iBAAM,EAAC,GAAG,EAAE;gBACb,MAAM,EAAE,SAAS;gBACjB,OAAO,EAAE,UAAU;aACtB,CAAC;SACL;KACJ,CAAC,CAAC;AACP,CAAC"}
|