Compare commits

..

19 Commits

Author SHA1 Message Date
raucao 6cbe82397f Merge pull request 'Add AGENTS.md' (#250) from chore/agents.md into master
Reviewed-on: #250
2026-07-25 15:33:49 +00:00
raucao a927d591c6 Add AGENTS.md
Release Drafter / Update release notes draft (pull_request) Failing after 2s
2026-07-25 17:32:49 +02:00
raucao 0f872c8f1e 7.5.0
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2025-01-20 15:39:11 -05:00
raucao 484a9ffcaf Merge pull request 'Add amountSats to expense items' (#249) from chore/update_schemas into master
Reviewed-on: #249
2025-01-20 20:35:11 +00:00
raucao 6e9f565587 Add more logs for IPFS failures
Release Drafter / Update release notes draft (pull_request) Successful in 4s
2025-01-20 15:32:50 -05:00
raucao f4634fe692 Add amountSats to expense items
closes #248
2025-01-20 15:31:19 -05:00
raucao 68968e1fbd Update Kosmos schemas 2025-01-20 14:41:41 -05:00
Râu Cao a2ebc609ea 7.4.0
continuous-integration/drone/push Build is passing
2023-08-29 15:03:03 +02:00
raucao beca6afc4f Merge pull request 'Add npm version/release script' (#247) from dev/versioning into master
continuous-integration/drone/push Build is passing
Reviewed-on: #247
2023-08-29 12:59:56 +00:00
Râu Cao 90223dd22e Add npm version script
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Release Drafter / Update release notes draft (pull_request) Successful in 2s
closes #46
2023-08-29 14:57:07 +02:00
bumi ea3a591a0c Merge pull request 'Improve data in development seeds/bootstrap' (#246) from dev/improve_seeds into master
continuous-integration/drone/push Build is passing
Reviewed-on: #246
2023-08-29 10:19:26 +00:00
Râu Cao e0f20d363c Pre-confirm some contributions and reimbursements on bootstrap
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Release Drafter / Update release notes draft (pull_request) Successful in 3s
2023-08-24 16:43:52 +02:00
Râu Cao 5e33381f2a Allow overriding confirmedAtBlock and vetoed in JS API 2023-08-24 16:43:18 +02:00
raucao 1f91a13f06 Merge pull request 'Update reimbursement to support migration' (#244) from feature/reimbursement_migrations into master
continuous-integration/drone/push Build is passing
Reviewed-on: #244
2023-08-24 14:04:22 +00:00
bumi 7d2a492fc9 Update reimbursement to support migration
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
Release Drafter / Update release notes draft (pull_request) Successful in 4s
2023-08-24 15:45:28 +02:00
Râu Cao 30490ce393 "Fix" default network name in hardhat config
continuous-integration/drone/push Build is passing
Some scripts require "hardhat" while others require "localhost". But we
can fix whatever doesn't work directly in the package config.
2023-08-24 14:52:38 +02:00
Râu Cao f0a71ca8f1 7.3.0
continuous-integration/drone/push Build is passing
2023-08-13 21:01:34 +02:00
Râu Cao 117918e66f Remove obsolete npm scripts 2023-08-13 20:59:09 +02:00
raucao d0d456b357 Merge pull request 'Migrate to proper RSK testnet deployment' (#242) from new-final-deploy into master
continuous-integration/drone/push Build is passing
Reviewed-on: #242
2023-08-13 18:54:35 +00:00
12 changed files with 202 additions and 31 deletions
+112
View File
@@ -0,0 +1,112 @@
# AGENTS.md
Guidance for AI agents working on this repository.
## Project overview
`@kredits/contracts` — Solidity smart contracts and a JavaScript (ethers v5)
wrapper for [Kosmos Kredits](https://wiki.kosmos.org/Kredits), a contribution
tracking DAO running on EVM chains (primarily RSK). Contributors earn kredits
for contributions; kredits are withdrawable as ERC20 tokens. All contracts are
upgradeable via OpenZeppelin hardhat-upgrades proxies.
## Tech stack
- Solidity ^0.8.0 (compiler 0.8.2), OpenZeppelin upgradeable contracts
- Hardhat (with @openzeppelin/hardhat-upgrades, hardhat-deploy, hardhat-waffle)
- JavaScript (CommonJS), ethers v5, ipfs-http-client
- Tests: mocha + chai + @nomicfoundation/hardhat-chai-matchers
- Lint: solhint (contracts), eslint (JS)
## Repository layout
- `contracts/` — Solidity smart contracts (see "Contracts" below)
- `lib/` — published JavaScript API wrapper (entry: `lib/kredits.js`)
- `lib/contracts/` — one wrapper class per contract, extending `Base`/`Record`
- `lib/serializers/` — IPFS JSON serializers (contributor, contribution)
- `lib/utils/` — ipfs, pagination, validator, preflight, deprecate, format-kredits
- `lib/abis/` — committed ABI JSON (regenerated by `npm run build:json`)
- `lib/addresses.json` — chainId → deployed contract addresses
- `scripts/` — hardhat CLI helpers (create-proxy, seeds, add-/list-*, build-json,
upgrade-example, import/, export/)
- `test/contracts/` — mocha tests (Contributor.js, Contribution.js)
- `config/seeds.js` — demo seed data
- `hardhat.config.js` — networks: hardhat (1337), rinkeby, rsk (RSK testnet);
injects `hre.kredits` (an initialized `Kredits` instance)
## Contracts
All in `contracts/`, all `Initializable` (OpenZeppelin upgradeable):
- `Contributor.sol` — contributor registry (account + IPFS profile hash).
Core team = contributor IDs 16 (hardcoded). `withdraw()` mints tokens for
confirmed, not-yet-withdrawn kredits.
- `Contribution.sol` — contribution records (ERC721-like ownership). Veto
period ~40320 blocks (~7 days @ 15s blocks). `add()` → veto window → confirmed.
- `Reimbursement.sol` — expense reimbursements, same veto pattern.
- `Token.sol` — ERC20 "Kredits" (symbol KS, 0 decimals). `mintFor` callable only
by the Contributor contract.
Contracts are independent and reference each other by address (set via
`setContributorContract`, `setContributionContract`, `setTokenContract`).
Wiring happens in `scripts/create-proxy.js`.
## Common commands
Bootstrap a local dev environment:
```
npm install
npm run devchain # hardhat node --network hardhat (separate terminal)
npm run bootstrap # build + deploy proxies + seeds (uses localhost)
```
Other:
```
npm run build # compile contracts + regenerate lib/abis
npm run deploy:dao # deploy upgradeable proxies (scripts/create-proxy.js)
npm run seeds # seed demo data
npm run fund # send devchain ETH to an address
npm test # hardhat test (requires devchain running)
npm run lint:contracts # solhint
npm run lint:wrapper # eslint lib/
```
Run a hardhat script: `hardhat run scripts/<name>.js --network localhost`
(or `--network rsk` for RSK testnet). Use `DEPLOY_KEY=<hex>` to override the
deploy account.
## Conventions
### JavaScript (eslint: `lib/`, scripts/, test/)
- CommonJS (`require`/`module.exports`)
- 2-space indentation; semicolons required
- Trailing commas in multiline arrays/objects (not in imports/exports)
- Space before named function parens: `function foo () {}`, `async () => {}`
- Async wrappers use `.then()` chains in older code; new code may use async/await
### Solidity (solhint: default + recommended)
- `pragma solidity ^0.8.0;`
- Upgradeable pattern: `import Initializable`, use `initialize()` (and
`reinitializer(n)` for upgrades) — never use constructors for state init
- Interfaces declared inline (e.g. `ContributorInterface`) for cross-contract calls
- Core-only / deployer-only / contributors-only modifiers guard privileged calls
### Upgradeable contract changes
- Do not use constructors to initialize state (use `initialize`/`reinitializer`)
- Do not change the order/types of existing storage variables (storage layout!)
- New storage vars go at the end of the contract
- See `scripts/upgrade-example.js` and `scripts/create-proxy.js`
## Tests
Mocha + hardhat-waffle + chai-matchers. `test/contracts/` only covers
Contributor and Contribution today. When changing contract code, add/adapt
tests there. Requires a running devchain (`npm run devchain`) for `npm test`.
## Networks & deployment
- `hardhat` (chainId 1337) — local devchain
- `rsk` (RSK testnet, https://rsk-testnet.kosmos.org) — primary test deployment
- `rinkeby` — legacy, configured but deprecated
- Deployed addresses are tracked per chainId in `lib/addresses.json` and must be
committed when deployment changes (see `npm run version` script)
+48 -11
View File
@@ -31,18 +31,55 @@ const contractCalls = [
wiki_username: 'Manuel', wiki_username: 'Manuel',
}, { gasLimit: 200000 }]], }, { gasLimit: 200000 }]],
['Contribution', 'add', [{ contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF', date: '2019-04-11', amount: 500, kind: 'dev', description: '[67P/kredits-contracts] Test this thing', url: '' }, { gasLimit: 350000 }]], ['Contribution', 'add', [{
['Contribution', 'add', [{ contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB', date: '2019-04-11', amount: 1500, kind: 'dev', description: '[67P/kredits-web] Reviewed stuff', url: '' }, { gasLimit: 350000 }]], contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF',
['Contribution', 'add', [{ contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF', date: '2019-04-11', amount: 5000, kind: 'dev', description: '[67P/kredits-contracts] Add tests', url: '' }, { gasLimit: 350000 }]], date: '2019-04-11', amount: 500, kind: 'dev',
['Contribution', 'add', [{ contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF', date: '2019-04-11', amount: 1500, kind: 'dev', description: '[67P/kredits-contracts] Introduce contribution token', url: '' }, { gasLimit: 350000 }]], description: '[67P/kredits-contracts] Test this thing',
['Contribution', 'add', [{ contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB', date: '2019-04-11', amount: 5000, kind: 'dev', description: '[67P/kredits-web] Expense UI, first draft', url: '' }, { gasLimit: 350000 }]], url: '',
confirmedAtBlock: 1,
}, { gasLimit: 350000 }]],
['Reimbursement', 'add', [{amount: 1116000, recipientId: 1, token: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', expenses: [ ['Contribution', 'add', [{
{ title: 'Server rent', description: 'Dedicated server: andromeda.kosmos.org, April 2020', amount: 61, currency: 'EUR', date: '2020-05-28' }, contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB',
{ title: 'Server rent', description: 'Dedicated server: centaurus.kosmos.org, April 2020', amount: 32, currency: 'EUR', date: '2020-05-28' } date: '2019-04-11', amount: 1500, kind: 'dev',
]}, { gasLimit: 300000 }]], description: '[67P/kredits-web] Reviewed stuff',
['Reimbursement', 'add', [{amount: 166800, recipientId: 2, token: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', expenses: [ url: '',
{ title: 'Domain kosmos.chat', description: 'Yearly registration fee for domain kosmos.chat', amount: 13.90, currency: 'EUR', date: '2020-05-30' } confirmedAtBlock: 1,
}, { gasLimit: 350000 }]],
['Contribution', 'add', [{
contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF',
date: '2019-04-11', amount: 5000, kind: 'dev',
description: '[67P/kredits-contracts] Add tests',
url: '',
confirmedAtBlock: 1,
}, { gasLimit: 350000 }]],
['Contribution', 'add', [{
contributorId: 1, contributorIpfsHash: 'QmWKCYGr2rSf6abUPaTYqf98urvoZxGrb7dbspFZA6oyVF',
date: '2019-04-11', amount: 1500, kind: 'dev',
description: '[67P/kredits-contracts] Introduce contribution token',
url: '',
}, { gasLimit: 350000 }]],
['Contribution', 'add', [{
contributorId: 2, contributorIpfsHash: 'QmcHzEeAM26HV2zHTf5HnZrCtCtGdEccL5kUtDakAB7ozB',
date: '2019-04-11', amount: 1500, kind: 'design',
description: '[67P/kredits-web] Expense UI, first draft',
url: '',
}, { gasLimit: 350000 }]],
['Reimbursement', 'add', [{ amount: 346800, recipientId: 2, token: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', expenses: [
{ title: 'Domain kosmos.social', description: 'Yearly registration fee for domain kosmos.social', amount: 69.00, currency: 'EUR', amountSats: 69216, date: '2020-04-30' },
], confirmedAtBlock: 1 }, { gasLimit: 300000 }]],
['Reimbursement', 'add', [{ amount: 1116000, recipientId: 1, token: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', expenses: [
{ title: 'Server rent', description: 'Dedicated server: andromeda.kosmos.org, April 2020', amount: 61, currency: 'EUR', amountSats: 61191, date: '2020-05-28' },
{ title: 'Server rent', description: 'Dedicated server: centaurus.kosmos.org, April 2020', amount: 32, currency: 'EUR', amountSats: 32201, date: '2020-05-28' },
], confirmedAtBlock: 1 }, { gasLimit: 300000 }]],
['Reimbursement', 'add', [{ amount: 166800, recipientId: 2, token: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', expenses: [
{ title: 'Domain kosmos.chat', description: 'Yearly registration fee for domain kosmos.chat', amount: 13.90, currency: 'EUR', amountSats: 13944, date: '2020-05-30' },
]}, { gasLimit: 300000 }]], ]}, { gasLimit: 300000 }]],
]; ];
+1 -1
View File
@@ -62,7 +62,7 @@ task("create-wallet", "Creates a new wallet json", async () => {
*/ */
module.exports = { module.exports = {
solidity: "0.8.2", solidity: "0.8.2",
defaultNetwork: "hardhat", defaultNetwork: "localhost",
networks: { networks: {
hardhat: { hardhat: {
chainId: 1337, chainId: 1337,
+1 -1
View File
@@ -1 +1 @@
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":true,"internalType":"address","name":"addedByAccount","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReimbursementAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"vetoedByAccount","type":"address"}],"name":"ReimbursementVetoed","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint32","name":"recipientId","type":"uint32"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"blocksToWait","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorContract","outputs":[{"internalType":"contract ContributorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"reimbursementId","type":"uint32"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"reimbursementId","type":"uint32"}],"name":"get","outputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"uint32","name":"recipientId","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"vetoed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"}],"name":"getContributorAddressById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributorAccount","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"reimbursements","outputs":[{"internalType":"uint32","name":"recipientId","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"vetoed","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reimbursementsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"}],"name":"setContributorContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"confirmedOnly","type":"bool"}],"name":"totalAmount","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"reimbursementId","type":"uint32"}],"name":"veto","outputs":[],"stateMutability":"nonpayable","type":"function"}] [{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":true,"internalType":"address","name":"addedByAccount","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReimbursementAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"id","type":"uint32"},{"indexed":false,"internalType":"address","name":"vetoedByAccount","type":"address"}],"name":"ReimbursementVetoed","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint32","name":"recipientId","type":"uint32"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"vetoed","type":"bool"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"blocksToWait","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorContract","outputs":[{"internalType":"contract ContributorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"reimbursementId","type":"uint32"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finishMigration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"reimbursementId","type":"uint32"}],"name":"get","outputs":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"uint32","name":"recipientId","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"vetoed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"contributorId","type":"uint32"}],"name":"getContributorAddressById","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributorAccount","type":"address"}],"name":"getContributorIdByAddress","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"migrationDone","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"reimbursements","outputs":[{"internalType":"uint32","name":"recipientId","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"hashDigest","type":"bytes32"},{"internalType":"uint8","name":"hashFunction","type":"uint8"},{"internalType":"uint8","name":"hashSize","type":"uint8"},{"internalType":"uint256","name":"confirmedAtBlock","type":"uint256"},{"internalType":"bool","name":"vetoed","type":"bool"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reimbursementsCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contributor","type":"address"}],"name":"setContributorContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"confirmedOnly","type":"bool"}],"name":"totalAmount","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"reimbursementId","type":"uint32"}],"name":"veto","outputs":[],"stateMutability":"nonpayable","type":"function"}]
+5 -1
View File
@@ -41,6 +41,8 @@ class Contribution extends Record {
async add (contributionAttr, callOptions = {}) { async add (contributionAttr, callOptions = {}) {
const contribution = new ContributionSerializer(contributionAttr); const contribution = new ContributionSerializer(contributionAttr);
const confirmedAtBlock = contributionAttr.confirmedAtBlock || 0;
const vetoed = contributionAttr.vetoed || false;
try { await contribution.validate(); } try { await contribution.validate(); }
catch (error) { return Promise.reject(error); } catch (error) { return Promise.reject(error); }
@@ -56,9 +58,11 @@ class Contribution extends Record {
ipfsHashAttr.hashDigest, ipfsHashAttr.hashDigest,
ipfsHashAttr.hashFunction, ipfsHashAttr.hashFunction,
ipfsHashAttr.hashSize, ipfsHashAttr.hashSize,
confirmedAtBlock,
vetoed,
]; ];
return this.contract.add(...contribution, 0, false, callOptions); return this.contract.add(...contribution, callOptions);
}); });
} }
+5
View File
@@ -52,6 +52,7 @@ class Contributor extends Record {
const jsonStr = contributor.serialize(); const jsonStr = contributor.serialize();
// console.log('Adding IPFS doc for', contributorAttr.account);
return this.ipfs return this.ipfs
.add(jsonStr) .add(jsonStr)
.then((ipfsHashAttr) => { .then((ipfsHashAttr) => {
@@ -62,7 +63,11 @@ class Contributor extends Record {
ipfsHashAttr.hashSize, ipfsHashAttr.hashSize,
]; ];
// console.log('Adding onchain record for', contributorAttr.account);
return this.contract.addContributor(...contributor, callOptions); return this.contract.addContributor(...contributor, callOptions);
}).catch(err => {
console.log('Failed to add IPFS document:', err.message);
throw(err);
}); });
} }
+4
View File
@@ -23,6 +23,8 @@ class Reimbursement extends Record {
const amount = parseInt(attrs.amount); const amount = parseInt(attrs.amount);
const token = attrs.token; const token = attrs.token;
const recipientId = attrs.recipientId; const recipientId = attrs.recipientId;
const confirmedAtBlock = attrs.confirmedAtBlock || 0;
const vetoed = attrs.vetoed || false;
const expenses = attrs.expenses.map((e) => new ExpenseSerializer(e)); const expenses = attrs.expenses.map((e) => new ExpenseSerializer(e));
let errorMessage; let errorMessage;
@@ -56,6 +58,8 @@ class Reimbursement extends Record {
ipfsHashAttr.hashDigest, ipfsHashAttr.hashDigest,
ipfsHashAttr.hashFunction, ipfsHashAttr.hashFunction,
ipfsHashAttr.hashSize, ipfsHashAttr.hashSize,
confirmedAtBlock,
vetoed,
]; ];
return this.contract.add(...reimbursement, callOptions); return this.contract.add(...reimbursement, callOptions);
+4
View File
@@ -29,6 +29,7 @@ class ExpenseSerializer {
description, description,
currency, currency,
amount, amount,
amountSats,
date, date,
url, url,
tags, tags,
@@ -42,6 +43,7 @@ class ExpenseSerializer {
description, description,
currency, currency,
amount, amount,
amountSats,
date, date,
'tags': tags || [], 'tags': tags || [],
'details': details || {}, 'details': details || {},
@@ -76,6 +78,7 @@ class ExpenseSerializer {
description, description,
currency, currency,
amount, amount,
amountSats,
date, date,
url, url,
tags, tags,
@@ -87,6 +90,7 @@ class ExpenseSerializer {
description, description,
currency, currency,
amount, amount,
amountSats,
date, date,
url, url,
tags, tags,
+7
View File
@@ -9,6 +9,13 @@ class IPFS {
} }
this._config = config; this._config = config;
this._ipfsAPI = ipfsClient.create(config); this._ipfsAPI = ipfsClient.create(config);
this._ipfsAPI.id().then(res => {
console.debug('IPFS ID:', res.id);
}).catch(e => {
console.debug('IPFS config:', config);
console.warn('Failed to initialize IPFS:', e.message);
});
} }
async catAndMerge (contractData, deserialize) { async catAndMerge (contractData, deserialize) {
+9 -9
View File
@@ -1,15 +1,15 @@
{ {
"name": "@kredits/contracts", "name": "@kredits/contracts",
"version": "7.2.0", "version": "7.5.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@kredits/contracts", "name": "@kredits/contracts",
"version": "7.2.0", "version": "7.5.0",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@kosmos/schemas": "^3.1.0", "@kosmos/schemas": "^3.2.0",
"ethers": "^5.4.7", "ethers": "^5.4.7",
"ipfs-http-client": "^56.0.3", "ipfs-http-client": "^56.0.3",
"multihashes": "^4.0.3", "multihashes": "^4.0.3",
@@ -1022,9 +1022,9 @@
} }
}, },
"node_modules/@kosmos/schemas": { "node_modules/@kosmos/schemas": {
"version": "3.1.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/@kosmos/schemas/-/schemas-3.1.0.tgz", "resolved": "https://registry.npmjs.org/@kosmos/schemas/-/schemas-3.2.0.tgz",
"integrity": "sha512-yOTK5WiXFDNAitPByMabE365aEEzFHgSUSgAssbJWt7BZ80HQSVu8XWrQiTbFbCkoIBmXwPP/RoxgXJQVgZTFQ==" "integrity": "sha512-GyWXmWcATcakmEdPOpafdckBgWFqcpSh+tB8nm11VGgtgA94pfoFhKZ3t88WELItKfuP/GFHgMiZmdMB3bSkdQ=="
}, },
"node_modules/@metamask/eth-sig-util": { "node_modules/@metamask/eth-sig-util": {
"version": "4.0.1", "version": "4.0.1",
@@ -20786,9 +20786,9 @@
} }
}, },
"@kosmos/schemas": { "@kosmos/schemas": {
"version": "3.1.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/@kosmos/schemas/-/schemas-3.1.0.tgz", "resolved": "https://registry.npmjs.org/@kosmos/schemas/-/schemas-3.2.0.tgz",
"integrity": "sha512-yOTK5WiXFDNAitPByMabE365aEEzFHgSUSgAssbJWt7BZ80HQSVu8XWrQiTbFbCkoIBmXwPP/RoxgXJQVgZTFQ==" "integrity": "sha512-GyWXmWcATcakmEdPOpafdckBgWFqcpSh+tB8nm11VGgtgA94pfoFhKZ3t88WELItKfuP/GFHgMiZmdMB3bSkdQ=="
}, },
"@metamask/eth-sig-util": { "@metamask/eth-sig-util": {
"version": "4.0.1", "version": "4.0.1",
+5 -7
View File
@@ -1,6 +1,6 @@
{ {
"name": "@kredits/contracts", "name": "@kredits/contracts",
"version": "7.2.0", "version": "7.5.0",
"description": "Smart contracts and JavaScript API for Kredits", "description": "Smart contracts and JavaScript API for Kredits",
"main": "./lib/kredits.js", "main": "./lib/kredits.js",
"directories": { "directories": {
@@ -22,11 +22,9 @@
"lint:contract-tests": "eslint apps/*/test", "lint:contract-tests": "eslint apps/*/test",
"lint:wrapper": "eslint lib/", "lint:wrapper": "eslint lib/",
"test": "hardhat test", "test": "hardhat test",
"test:token": "cd apps/token && npm run test", "setup-git-hooks": "sh scripts/git-hooks/install",
"test:contributor": "cd apps/contributor && npm run test", "preversion": "npm test && npm run build",
"test:contribution": "cd apps/contribution && npm run test", "version": "git add lib/abis"
"test:proposal": "cd apps/proposal && npm run test",
"setup-git-hooks": "sh scripts/git-hooks/install"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@@ -68,7 +66,7 @@
"yargs": "^15.0.0" "yargs": "^15.0.0"
}, },
"dependencies": { "dependencies": {
"@kosmos/schemas": "^3.1.0", "@kosmos/schemas": "^3.2.0",
"ethers": "^5.4.7", "ethers": "^5.4.7",
"ipfs-http-client": "^56.0.3", "ipfs-http-client": "^56.0.3",
"multihashes": "^4.0.3", "multihashes": "^4.0.3",
+1 -1
View File
@@ -39,7 +39,7 @@ async function main() {
contractWrapper.contract[method]; contractWrapper.contract[method];
try { try {
// console.log('trying', func); // console.log('trying', contractName, method, args);
const result = await func.apply(contractWrapper, args); const result = await func.apply(contractWrapper, args);
// console.log('result:', result); // console.log('result:', result);
await result.wait(); await result.wait();