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.
Files changed (123) hide show
  1. package/.claude/settings.local.json +12 -0
  2. package/.env.example +2 -2
  3. package/.travis.yml +11 -11
  4. package/AGENTS.md +35 -0
  5. package/CHANGELOG.md +166 -0
  6. package/CLAUDE.md +75 -0
  7. package/DOCUMENTATION.md +380 -0
  8. package/LICENSE +21 -21
  9. package/README.md +429 -238
  10. package/dist/actions.d.ts +41 -10
  11. package/dist/actions.js +126 -23
  12. package/dist/actions.js.map +1 -1
  13. package/dist/adapters/base.adapter.d.ts +43 -25
  14. package/dist/adapters/base.adapter.js +79 -49
  15. package/dist/adapters/base.adapter.js.map +1 -1
  16. package/dist/adapters/mongodb.adapter.d.ts +44 -37
  17. package/dist/adapters/mongodb.adapter.js +363 -158
  18. package/dist/adapters/mongodb.adapter.js.map +1 -1
  19. package/dist/adapters/postgresql.adapter.d.ts +66 -0
  20. package/dist/adapters/postgresql.adapter.js +598 -0
  21. package/dist/adapters/postgresql.adapter.js.map +1 -0
  22. package/dist/adapters/sqlite.adapter.d.ts +57 -41
  23. package/dist/adapters/sqlite.adapter.js +561 -397
  24. package/dist/adapters/sqlite.adapter.js.map +1 -1
  25. package/dist/api.d.ts +6 -6
  26. package/dist/api.js +181 -55
  27. package/dist/api.js.map +1 -1
  28. package/dist/config.d.ts +19 -16
  29. package/dist/config.js +21 -18
  30. package/dist/config.js.map +1 -1
  31. package/dist/contracts/coinflip.contract.d.ts +9 -14
  32. package/dist/contracts/coinflip.contract.js +232 -94
  33. package/dist/contracts/coinflip.contract.js.map +1 -1
  34. package/dist/contracts/contract.d.ts +3 -0
  35. package/dist/contracts/contract.js +26 -0
  36. package/dist/contracts/contract.js.map +1 -0
  37. package/dist/contracts/dice.contract.d.ts +10 -29
  38. package/dist/contracts/dice.contract.js +217 -155
  39. package/dist/contracts/dice.contract.js.map +1 -1
  40. package/dist/contracts/exchange.contract.d.ts +11 -0
  41. package/dist/contracts/exchange.contract.js +492 -0
  42. package/dist/contracts/exchange.contract.js.map +1 -0
  43. package/dist/contracts/lotto.contract.d.ts +16 -20
  44. package/dist/contracts/lotto.contract.js +238 -246
  45. package/dist/contracts/lotto.contract.js.map +1 -1
  46. package/dist/contracts/nft.contract.d.ts +28 -0
  47. package/dist/contracts/nft.contract.js +598 -0
  48. package/dist/contracts/nft.contract.js.map +1 -0
  49. package/dist/contracts/poll.contract.d.ts +4 -0
  50. package/dist/contracts/poll.contract.js +105 -0
  51. package/dist/contracts/poll.contract.js.map +1 -0
  52. package/dist/contracts/rps.contract.d.ts +9 -0
  53. package/dist/contracts/rps.contract.js +217 -0
  54. package/dist/contracts/rps.contract.js.map +1 -0
  55. package/dist/contracts/tipjar.contract.d.ts +4 -0
  56. package/dist/contracts/tipjar.contract.js +60 -0
  57. package/dist/contracts/tipjar.contract.js.map +1 -0
  58. package/dist/contracts/token.contract.d.ts +4 -0
  59. package/dist/contracts/token.contract.js +311 -0
  60. package/dist/contracts/token.contract.js.map +1 -0
  61. package/dist/exchanges/bittrex.d.ts +6 -6
  62. package/dist/exchanges/bittrex.js +34 -34
  63. package/dist/exchanges/coingecko.d.ts +11 -0
  64. package/dist/exchanges/coingecko.js +57 -0
  65. package/dist/exchanges/coingecko.js.map +1 -0
  66. package/dist/exchanges/exchange.d.ts +16 -9
  67. package/dist/exchanges/exchange.js +80 -26
  68. package/dist/exchanges/exchange.js.map +1 -1
  69. package/dist/hive-rates.d.ts +34 -9
  70. package/dist/hive-rates.js +208 -75
  71. package/dist/hive-rates.js.map +1 -1
  72. package/dist/index.d.ts +19 -11
  73. package/dist/index.js +47 -32
  74. package/dist/index.js.map +1 -1
  75. package/dist/streamer.d.ts +233 -93
  76. package/dist/streamer.js +1063 -545
  77. package/dist/streamer.js.map +1 -1
  78. package/dist/test.d.ts +1 -1
  79. package/dist/test.js +24 -25
  80. package/dist/test.js.map +1 -1
  81. package/dist/types/hive-stream.d.ts +106 -6
  82. package/dist/types/hive-stream.js +2 -2
  83. package/dist/types/rates.d.ts +47 -0
  84. package/dist/types/rates.js +29 -0
  85. package/dist/types/rates.js.map +1 -0
  86. package/dist/utils.d.ts +334 -27
  87. package/dist/utils.js +960 -261
  88. package/dist/utils.js.map +1 -1
  89. package/ecosystem.config.js +17 -17
  90. package/examples/contracts/README.md +8 -0
  91. package/examples/contracts/exchange.ts +38 -0
  92. package/examples/contracts/poll.ts +21 -0
  93. package/examples/contracts/rps.ts +19 -0
  94. package/examples/contracts/tipjar.ts +19 -0
  95. package/jest.config.js +8 -8
  96. package/package.json +54 -48
  97. package/test-contract-block.md +18 -18
  98. package/tests/actions.spec.ts +252 -0
  99. package/tests/adapters/actions-persistence.spec.ts +144 -0
  100. package/tests/adapters/postgresql.adapter.spec.ts +127 -0
  101. package/tests/adapters/sqlite.adapter.spec.ts +180 -42
  102. package/tests/contracts/coinflip.contract.spec.ts +94 -132
  103. package/tests/contracts/dice.contract.spec.ts +87 -160
  104. package/tests/contracts/entrants.json +728 -728
  105. package/tests/contracts/exchange.contract.spec.ts +84 -0
  106. package/tests/contracts/lotto.contract.spec.ts +59 -324
  107. package/tests/contracts/nft.contract.spec.ts +948 -0
  108. package/tests/contracts/token.contract.spec.ts +90 -0
  109. package/tests/exchanges/coingecko.exchange.spec.ts +169 -0
  110. package/tests/exchanges/exchange.base.spec.ts +246 -0
  111. package/tests/helpers/mock-adapter.ts +214 -0
  112. package/tests/helpers/mock-fetch.ts +165 -0
  113. package/tests/hive-chain-features.spec.ts +238 -0
  114. package/tests/hive-rates.spec.ts +443 -0
  115. package/tests/integration/hive-rates.integration.spec.ts +35 -0
  116. package/tests/setup.ts +29 -18
  117. package/tests/streamer-actions.spec.ts +274 -0
  118. package/tests/streamer.spec.ts +342 -152
  119. package/tests/types/rates.spec.ts +216 -0
  120. package/tests/utils.spec.ts +113 -95
  121. package/tsconfig.build.json +3 -22
  122. package/tslint.json +20 -20
  123. 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,4 @@
1
+ export interface TipJarContractOptions {
2
+ name?: string;
3
+ }
4
+ export declare function createTipJarContract(options?: TipJarContractOptions): import("..").ContractDefinition;
@@ -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"}
@@ -0,0 +1,4 @@
1
+ export interface TokenContractOptions {
2
+ name?: string;
3
+ }
4
+ export declare function createTokenContract(options?: TokenContractOptions): import("..").ContractDefinition;