mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-03 18:01:39 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
354fdabdc4 | ||
|
|
7c4586ce90 | ||
|
|
6d27b926f6 | ||
|
|
f74bdc1d79 | ||
|
|
8522cb8d47 | ||
|
|
30475b9fbd | ||
|
|
1388a673e5 | ||
|
|
ac8c153b28 | ||
|
|
ee12bf684e | ||
|
|
63dc68caac | ||
|
|
ec57c76a2a | ||
|
|
99e9eefffb | ||
|
|
eb0777ebb4 | ||
|
|
ed5ee034b8 | ||
|
|
bb2972b527 | ||
|
|
45b474c9a6 | ||
|
|
99747c022e | ||
|
|
d9a2689469 | ||
|
|
08d8c7eda0 | ||
|
|
4dd23f1be8 | ||
|
|
0ebc988a68 | ||
|
|
9b8af84393 | ||
|
|
ff1ccd7c78 | ||
|
|
3176cc661a | ||
|
|
9ba387f2e4 | ||
|
|
c87dffd6da | ||
|
|
0cf69f5a59 | ||
|
|
babab1e09e | ||
|
|
6f5b079f51 | ||
|
|
9908669be0 | ||
|
|
c2f3e66405 | ||
|
|
b24c4668ed | ||
|
|
fcca387d9a | ||
|
|
97cc6a0d21 | ||
|
|
737565344d | ||
|
|
72f42afb81 | ||
|
|
0a2b91c9ac | ||
|
|
83b8fc597a | ||
|
|
0d4f2946f3 | ||
|
|
305efbea5d | ||
|
|
23f077ce75 | ||
|
|
d667c3c604 | ||
|
|
0502f52ec0 | ||
|
|
40f50bf37a | ||
|
|
0e0a46741f | ||
|
|
5b784659af | ||
|
|
e2f24eef8e | ||
|
|
aa43770bf4 | ||
|
|
45bc823de0 | ||
|
|
1250468f69 | ||
|
|
e94ce3b1cc | ||
|
|
ebb89facbd | ||
|
|
648b089c48 | ||
|
|
0befb6d431 | ||
|
|
35f2ad604c | ||
|
|
e139aee2b3 | ||
|
|
b57bea6f7b | ||
|
|
1828d2e710 | ||
|
|
04d929aae9 | ||
|
|
b51c36645e | ||
|
|
bd1ea5042e | ||
|
|
af4c66bc79 | ||
|
|
2d1f820451 | ||
|
|
179add9e12 | ||
|
|
9d3264256a | ||
|
|
fb234ed339 | ||
|
|
bb7724ece1 | ||
|
|
c67a7823a6 | ||
|
|
518109e9df | ||
|
|
e38a045de3 | ||
|
|
ba82d707d0 | ||
|
|
f366dd8cf2 | ||
|
|
dc6f02a000 | ||
|
|
b81bdebd64 | ||
|
|
6127d80f2a | ||
|
|
49c8a8c6d0 | ||
|
|
e2e0c35008 | ||
|
|
1de6eda49f | ||
|
|
000a0893c3 | ||
|
|
0a68ab682d | ||
|
|
54e51768c0 | ||
|
|
4eb294d856 | ||
|
|
e3b8f2cffe | ||
|
|
c158904efc | ||
|
|
f250082fff | ||
|
|
67432d3fdf | ||
|
|
0ff4299061 | ||
|
|
8ceb89053f | ||
|
|
6fbcb7cef5 | ||
|
|
f8d362352d | ||
|
|
ce3d073abd | ||
|
|
0e8b92e53d | ||
|
|
27d4dfcdfd | ||
|
|
38096db2dd | ||
|
|
bbb093b171 | ||
|
|
98bdf92d70 | ||
|
|
e572d7a626 | ||
|
|
aff4e3523c | ||
|
|
9972c5e40a | ||
|
|
2915ba2933 | ||
|
|
3d9264dae4 | ||
|
|
d030dbcfde | ||
|
|
60cede383a | ||
|
|
7ef06e8d05 | ||
|
|
e8475dbd8d | ||
|
|
3353d9f622 | ||
|
|
893631eb4c | ||
|
|
2286708d56 | ||
|
|
553cff37a1 | ||
|
|
7806c07381 | ||
|
|
b7a40ac3d7 | ||
|
|
5280209075 | ||
|
|
e0ebe92361 | ||
|
|
5c3966a9d6 | ||
|
|
38ca7b246b | ||
|
|
d9f2b21812 | ||
|
|
fb9f41248f | ||
|
|
4087fdd79e | ||
|
|
6bb2c2143e | ||
|
|
dae01698ef | ||
|
|
b65e844824 | ||
|
|
c64c506c52 | ||
|
|
889186ec3e | ||
|
|
9b3c89785e | ||
|
|
cfce4ba460 | ||
|
|
3cb72d89e9 | ||
|
|
cb6fb10c3c | ||
|
|
0c5f052f86 | ||
|
|
c36dc537ef | ||
|
|
4af64c8524 | ||
|
|
767e91f720 | ||
|
|
38447af730 | ||
|
|
94fb4dceac | ||
|
|
cbb98481c8 | ||
|
|
538806678d |
@@ -2,6 +2,7 @@
|
|||||||
name = "cz_conventional_commits"
|
name = "cz_conventional_commits"
|
||||||
tag_format = "v$version"
|
tag_format = "v$version"
|
||||||
version_scheme = "semver"
|
version_scheme = "semver"
|
||||||
version = "0.5.19"
|
version = "0.5.27"
|
||||||
update_changelog_on_bump = true
|
update_changelog_on_bump = true
|
||||||
major_version_zero = true
|
major_version_zero = true
|
||||||
|
changelog_file = "./docs/docs/changelog/index.md"
|
||||||
|
|||||||
@@ -0,0 +1,427 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "app/cosmos-sdk",
|
||||||
|
"path": "app",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"module",
|
||||||
|
"cosmos"
|
||||||
|
],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/module-manager"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"protobuf",
|
||||||
|
"cosmos"
|
||||||
|
],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/messages-and-queries"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"rpc",
|
||||||
|
"protobuf",
|
||||||
|
"service",
|
||||||
|
"cosmos"
|
||||||
|
],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/msg-services"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"protobuf",
|
||||||
|
"rpc",
|
||||||
|
"cosmos",
|
||||||
|
"query"
|
||||||
|
],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/query-services"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"cosmos",
|
||||||
|
"depinject",
|
||||||
|
"sdk"
|
||||||
|
],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/depinject"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "app/ibc",
|
||||||
|
"path": "app",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"cosmos",
|
||||||
|
"interchain",
|
||||||
|
"accounts"
|
||||||
|
],
|
||||||
|
"url": "https://ibc.cosmos.network/v8/apps/interchain-accounts/overview/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://ibc.cosmos.network/v8/apps/transfer/overview/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.osmosis.zone/osmosis-core/asset-info/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.osmosis.zone/osmosis-core/modules/tokenfactory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"usdc",
|
||||||
|
"mint",
|
||||||
|
"cosmos",
|
||||||
|
"noble"
|
||||||
|
],
|
||||||
|
"url": "https://docs.noble.xyz/cctp/mint"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"usdc"
|
||||||
|
],
|
||||||
|
"url": "https://docs.noble.xyz/cctp/mint_forward"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.evmos.org/protocol/modules/erc20"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.nomic.io/nbtc"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "crypto/mpc",
|
||||||
|
"path": "crypto/mpc",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"mpc",
|
||||||
|
"wallet",
|
||||||
|
"security",
|
||||||
|
"advanced cryptography"
|
||||||
|
],
|
||||||
|
"url": "https://csrc.nist.gov/CSRC/media/Events/NTCW19/papers/paper-DKLS.pdf"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "crypto/ucan",
|
||||||
|
"path": "crypto/ucan",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://raw.githubusercontent.com/ucan-wg/spec/refs/heads/main/README.md"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "crypto/zkp",
|
||||||
|
"path": "crypto/accumulator",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://eprint.iacr.org/2021/1672.pdf"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "gateway/handlers",
|
||||||
|
"path": "pkg/gateway/handlers",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://echo.labstack.com/docs/cookbook/sse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://echo.labstack.com/docs/cookbook/websocket"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://echo.labstack.com/docs/cookbook/subdomain"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "gateway/database",
|
||||||
|
"path": "pkg/gateway/internal/database",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.tigerbeetle.com/coding/data-modeling"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.tigerbeetle.com/coding/two-phase-transfers"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.tigerbeetle.com/coding/reliable-transaction-submission"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"currency"
|
||||||
|
],
|
||||||
|
"url": "https://docs.tigerbeetle.com/coding/recipes/currency-exchange"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"balance"
|
||||||
|
],
|
||||||
|
"url": "https://docs.tigerbeetle.com/coding/recipes/balance-conditional-transfers"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.tigerbeetle.com/reference/account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.tigerbeetle.com/reference/transfer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.substreams.dev/documentation/consume/packages"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.substreams.dev/documentation/consume/sql/deployable-services/local-service"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.substreams.dev/tutorials/cosmos/injective/foundational"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "vault/handlers",
|
||||||
|
"path": "pkg/vault/handlers",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://echo.labstack.com/docs/cookbook/jwt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://echo.labstack.com/docs/middleware/secure"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "vault/database",
|
||||||
|
"path": "pkg/vault/internal/database",
|
||||||
|
"docs": [
|
||||||
|
"https://dexie.org/docs/ExportImport/dexie-export-import",
|
||||||
|
"https://dexie.org/docs/API-Reference#quick-reference",
|
||||||
|
"https://templ.guide/syntax-and-usage/script-templates"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pkl/ipfs",
|
||||||
|
"path": "pkl/ipfs.net",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://github.com/ipfs/kubo/blob/master/docs/config.md"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://pkl-lang.org/main/current/language-reference/index.html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pkl/matrix",
|
||||||
|
"path": "pkl/matrix.net",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://pkl-lang.org/main/current/language-reference/index.html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pkl/chain",
|
||||||
|
"path": "pkl/sonr.chain",
|
||||||
|
"docs": [
|
||||||
|
"https://tutorials.cosmos.network/tutorials/9-path-to-prod/5-network.html",
|
||||||
|
"https://tutorials.cosmos.network/tutorials/9-path-to-prod/4-genesis.html",
|
||||||
|
"https://pkl-lang.org/main/current/language-reference/index.html",
|
||||||
|
"https://docs.cosmos.network/v0.50/user/run-node/run-testnet"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pkl/hway",
|
||||||
|
"path": "pkl/sonr.hway",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://pkl-lang.org/main/current/language-reference/index.html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pkl/motr",
|
||||||
|
"path": "pkl/sonr.motr",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://pkl-lang.org/main/current/language-reference/index.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://web.dev/learn/pwa/service-workers/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "x/did",
|
||||||
|
"path": "proto/did",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/packages/orm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/protobuf-annotations"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/modules/auth"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/packages/collections"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/modules/bank"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "x/dwn",
|
||||||
|
"path": "proto/dwn",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/protobuf-annotations"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/packages/orm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/modules/authz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/packages/collections"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/modules/gov"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/modules/staking"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "x/svc",
|
||||||
|
"path": "proto/svc",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/packages/collections"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/protobuf-annotations"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/packages/orm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/modules/group"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/modules/nft"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "repo/ci-cd",
|
||||||
|
"path": "deploy",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/tooling/cosmovisor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://f1bonacc1.github.io/process-compose/configuration/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.nomic.io/network/ibc-relayer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://www.jetify.com/docs/devbox"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://taskfile.dev/reference/cli"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://taskfile.dev/reference/schema"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://taskfile.dev/reference/templating/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "repo/docs",
|
||||||
|
"path": "docs",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://squidfunk.github.io/mkdocs-material/reference/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://github.com/mkdocs/catalog/blob/main/README.md"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
ROOT_DIR=$(git rev-parse --show-toplevel)
|
|
||||||
|
|
||||||
|
|
||||||
Executable
+63
@@ -0,0 +1,63 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ROOT_DIR=$(git rev-parse --show-toplevel)
|
||||||
|
|
||||||
|
# Extract scope name and path using jq, and pass it to fzf for selection
|
||||||
|
SCOPE=$(cat "$ROOT_DIR/.github/scopes.json" | jq -r '.[] | "\(.name)"' | fzf --prompt "Select scope:")
|
||||||
|
DOCS=$(cat "$ROOT_DIR/.github/scopes.json" | jq -r ".[] | select(.name == \"$SCOPE\") | .docs[].url")
|
||||||
|
|
||||||
|
# Write Title
|
||||||
|
TITLE=$(gum input --placeholder "Issue Title...")
|
||||||
|
|
||||||
|
# Write Goal
|
||||||
|
GOAL=$(mods --role "determine-issue-goal" "$SCOPE $TITLE")
|
||||||
|
|
||||||
|
# Input Requirements
|
||||||
|
REQUIREMENTS=()
|
||||||
|
while true; do
|
||||||
|
if [ ${#REQUIREMENTS[@]} -ge 2 ]; then
|
||||||
|
if ! gum confirm "Do you want to add another requirement?"; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
REQUIREMENT=$(gum input --placeholder "Add a requirement...")
|
||||||
|
if [ -n "$REQUIREMENT" ]; then
|
||||||
|
REQUIREMENTS+=("$REQUIREMENT")
|
||||||
|
else
|
||||||
|
echo "Requirement cannot be empty. Please enter a valid requirement."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
create_body() {
|
||||||
|
echo "### Goal(s):"
|
||||||
|
echo "$GOAL"
|
||||||
|
echo "### Requirements:"
|
||||||
|
for i in "${!REQUIREMENTS[@]}"; do
|
||||||
|
echo "$(($i + 1)). ${REQUIREMENTS[$i]}"
|
||||||
|
done
|
||||||
|
echo "### Resources:"
|
||||||
|
while IFS= read -r doc; do
|
||||||
|
echo "- $doc"
|
||||||
|
done <<< "$DOCS"
|
||||||
|
}
|
||||||
|
|
||||||
|
ISSUE_BODY=$(create_body)
|
||||||
|
|
||||||
|
# Function to collect output
|
||||||
|
preview_output() {
|
||||||
|
echo "# ($SCOPE) $TITLE"
|
||||||
|
echo "$ISSUE_BODY"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Display the formatted output
|
||||||
|
preview_output | gum format
|
||||||
|
|
||||||
|
# Confirm to create a GitHub issue
|
||||||
|
if gum confirm "Do you want to create a new GitHub issue with this information?"; then
|
||||||
|
# Create a new GitHub issue using the gh CLI
|
||||||
|
gh issue create --repo onsonr/sonr --title "($SCOPE) $TITLE" --body "$ISSUE_BODY"
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
name: Run All Checks
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
merge_group:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test-builds:
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Run Build Tests
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: onsonr/sonr
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: "1.23"
|
||||||
|
check-latest: true
|
||||||
|
- name: Run Sonrd Build
|
||||||
|
run: make build
|
||||||
|
- name: Run Hway Build
|
||||||
|
run: make build-hway
|
||||||
|
- name: Run Motr Build
|
||||||
|
run: make build-motr
|
||||||
|
|
||||||
|
test-unit:
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Run Unit Tests
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: onsonr/sonr
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: "1.23"
|
||||||
|
check-latest: true
|
||||||
|
- run: make test-unit
|
||||||
|
|
||||||
|
test-race:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name == 'merge_group'
|
||||||
|
name: Run Race Tests
|
||||||
|
continue-on-error: true
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: onsonr/sonr
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: "1.23"
|
||||||
|
check-latest: true
|
||||||
|
- run: make test-race
|
||||||
|
|
||||||
|
test-cover:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.event_name == 'merge_group'
|
||||||
|
name: Run Coverage Tests
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: onsonr/sonr
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: "1.23"
|
||||||
|
check-latest: true
|
||||||
|
- run: make test-cover
|
||||||
|
|
||||||
|
goreleaser-check:
|
||||||
|
if: github.event_name == 'merge_group'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Check GoReleaser Config
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: onsonr/sonr
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: "1.23"
|
||||||
|
check-latest: true
|
||||||
|
|
||||||
|
- name: Check GoReleaser Config
|
||||||
|
uses: goreleaser/goreleaser-action@v6
|
||||||
|
with:
|
||||||
|
distribution: goreleaser-pro
|
||||||
|
version: latest
|
||||||
|
args: check
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||||
|
|
||||||
|
- name: GoReleaser Dry Run
|
||||||
|
uses: goreleaser/goreleaser-action@v6
|
||||||
|
with:
|
||||||
|
distribution: goreleaser-pro
|
||||||
|
version: latest
|
||||||
|
args: release --snapshot --clean --skip=publish
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
name: Deploy Networks
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v*"
|
||||||
|
branches:
|
||||||
|
- develop
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
reboot-devnet:
|
||||||
|
name: Devnet Deploy
|
||||||
|
runs-on: goliath
|
||||||
|
environment: "Devnet"
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
branch: develop
|
||||||
|
|
||||||
|
- name: Stop Existing Network
|
||||||
|
continue-on-error: true
|
||||||
|
run: |
|
||||||
|
make stop-uds
|
||||||
|
make clean
|
||||||
|
|
||||||
|
- name: Start Updated Network
|
||||||
|
run: |
|
||||||
|
make start-uds
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
name: PR Labeler
|
name: PR Labeler
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
types: [opened]
|
types: [opened, edited]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
name: Publish Docs via GitHub Pages
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
paths:
|
||||||
|
- "docs/**"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Configure Git Credentials
|
||||||
|
run: |
|
||||||
|
git config user.name github-actions[bot]
|
||||||
|
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: 3.x
|
||||||
|
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
|
||||||
|
- uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
key: mkdocs-material-${{ env.cache_id }}
|
||||||
|
path: .cache
|
||||||
|
restore-keys: |
|
||||||
|
mkdocs-material-
|
||||||
|
- run: pip install mkdocs-material
|
||||||
|
- run: cd docs && mkdocs gh-deploy --force
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Upload Public Assets
|
name: Publish Versioned Assets
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
@@ -23,74 +23,3 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
input: proto
|
input: proto
|
||||||
buf_token: ${{ secrets.BUF_TOKEN }}
|
buf_token: ${{ secrets.BUF_TOKEN }}
|
||||||
|
|
||||||
buf_push_thirdparty:
|
|
||||||
name: Publish to buf.build/onsonr/thirdparty
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
# Run `git checkout`
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
# Install the `buf` CLI
|
|
||||||
- uses: bufbuild/buf-setup-action@v1
|
|
||||||
# Push only the Input in `proto` to the BSR
|
|
||||||
- uses: bufbuild/buf-push-action@v1
|
|
||||||
continue-on-error: true
|
|
||||||
with:
|
|
||||||
input: third_party/proto
|
|
||||||
buf_token: ${{ secrets.BUF_TOKEN }}
|
|
||||||
|
|
||||||
upload_motr_dwn:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Publish to configs.sonr.id
|
|
||||||
steps:
|
|
||||||
- name: checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: "1.23"
|
|
||||||
check-latest: true
|
|
||||||
|
|
||||||
- name: Setup go-task / task / taskfile
|
|
||||||
uses: rnorton5432/setup-task@v1
|
|
||||||
|
|
||||||
- name: Build DWN WASM
|
|
||||||
run: task dwn:build
|
|
||||||
|
|
||||||
- name: Upload WASM to R2
|
|
||||||
continue-on-error: true
|
|
||||||
uses: ryand56/r2-upload-action@latest
|
|
||||||
with:
|
|
||||||
r2-account-id: ${{ secrets.R2_ACCOUNT_ID }}
|
|
||||||
r2-access-key-id: ${{ secrets.R2_ACCESS_KEY_ID }}
|
|
||||||
r2-secret-access-key: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
|
||||||
r2-bucket: nebula
|
|
||||||
source-dir: ./build/app.wasm
|
|
||||||
destination-dir: wasm
|
|
||||||
|
|
||||||
- name: Upload SW JS to R2
|
|
||||||
continue-on-error: true
|
|
||||||
uses: ryand56/r2-upload-action@latest
|
|
||||||
with:
|
|
||||||
r2-account-id: ${{ secrets.R2_ACCOUNT_ID }}
|
|
||||||
r2-access-key-id: ${{ secrets.R2_ACCESS_KEY_ID }}
|
|
||||||
r2-secret-access-key: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
|
||||||
r2-bucket: nebula
|
|
||||||
source-dir: ./pkg/motr/static/sw.js
|
|
||||||
destination-dir: js
|
|
||||||
|
|
||||||
upload_nebula_cdn:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Publish to cdn.sonr.id
|
|
||||||
steps:
|
|
||||||
- name: checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Upload to R2
|
|
||||||
uses: ryand56/r2-upload-action@latest
|
|
||||||
with:
|
|
||||||
r2-account-id: ${{ secrets.R2_ACCOUNT_ID }}
|
|
||||||
r2-access-key-id: ${{ secrets.R2_ACCESS_KEY_ID }}
|
|
||||||
r2-secret-access-key: ${{ secrets.R2_SECRET_ACCESS_KEY }}
|
|
||||||
r2-bucket: nebula
|
|
||||||
source-dir: pkg/nebula/assets
|
|
||||||
destination-dir: .
|
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
name: Run Tests
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- feature/*
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test-unit:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Run Unit Tests
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: onsonr/sonr
|
|
||||||
fetch-depth: 0
|
|
||||||
fetch-tags: true
|
|
||||||
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: "1.23"
|
|
||||||
check-latest: true
|
|
||||||
- run: make test-unit
|
|
||||||
|
|
||||||
test-race:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Run Race Tests
|
|
||||||
continue-on-error: true
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: onsonr/sonr
|
|
||||||
fetch-depth: 0
|
|
||||||
fetch-tags: true
|
|
||||||
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: "1.23"
|
|
||||||
check-latest: true
|
|
||||||
- run: make test-race
|
|
||||||
|
|
||||||
test-cover:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Run Coverage Tests
|
|
||||||
continue-on-error: true
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: onsonr/sonr
|
|
||||||
fetch-depth: 0
|
|
||||||
fetch-tags: true
|
|
||||||
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: "1.23"
|
|
||||||
check-latest: true
|
|
||||||
- run: make test-cover
|
|
||||||
@@ -1,17 +1,51 @@
|
|||||||
name: Scheduled Release
|
name: Versioned Release
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- v*
|
- "v[0-9]+.[0-9]+.[0-9]+"
|
||||||
|
workflow_dispatch:
|
||||||
|
repository_dispatch:
|
||||||
|
types: [trigger-release]
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
check-release:
|
||||||
|
name: Check Existing Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
release_exists: ${{ steps.check.outputs.release_exists }}
|
||||||
|
is_tag: ${{ steps.check-ref.outputs.is_tag }}
|
||||||
|
ref_name: ${{ steps.check-ref.outputs.ref_name }}
|
||||||
|
steps:
|
||||||
|
- name: Determine ref type and name
|
||||||
|
id: check-ref
|
||||||
|
run: |
|
||||||
|
if [[ $GITHUB_REF == refs/tags/* ]]; then
|
||||||
|
echo "is_tag=true" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "ref_name=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
|
||||||
|
else
|
||||||
|
echo "is_tag=false" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "ref_name=${GITHUB_REF#refs/heads/}" >> "$GITHUB_OUTPUT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check if release exists
|
||||||
|
id: check
|
||||||
|
if: steps.check-ref.outputs.is_tag == 'true'
|
||||||
|
run: |
|
||||||
|
RELEASE_EXISTS=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
|
||||||
|
"https://api.github.com/repos/onsonr/sonr/releases/tags/${GITHUB_REF#refs/tags/}" \
|
||||||
|
| jq -r 'if .message == "Not Found" then "false" else "true" end')
|
||||||
|
echo "release_exists=$RELEASE_EXISTS" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
goreleaser:
|
goreleaser:
|
||||||
name: Release motr, sonrd, and DWN
|
name: Run GoReleaser
|
||||||
|
needs: check-release
|
||||||
|
if: |
|
||||||
|
(needs.check-release.outputs.is_tag == 'true' && needs.check-release.outputs.release_exists == 'false') ||
|
||||||
|
(needs.check-release.outputs.is_tag == 'false')
|
||||||
permissions: write-all
|
permissions: write-all
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -22,6 +56,18 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
fetch-tags: true
|
fetch-tags: true
|
||||||
|
|
||||||
|
- name: Set up release configuration
|
||||||
|
id: setup
|
||||||
|
run: |
|
||||||
|
if [[ "${{ needs.check-release.outputs.is_tag }}" == "true" ]]; then
|
||||||
|
echo "Using tag configuration"
|
||||||
|
git checkout ${{ needs.check-release.outputs.ref_name }}
|
||||||
|
echo "args=release --clean" >> "$GITHUB_OUTPUT"
|
||||||
|
else
|
||||||
|
echo "Using snapshot configuration"
|
||||||
|
echo "args=release --snapshot --clean" >> "$GITHUB_OUTPUT"
|
||||||
|
fi
|
||||||
|
|
||||||
- uses: actions/setup-go@v5
|
- uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: "1.23"
|
go-version: "1.23"
|
||||||
@@ -38,7 +84,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
distribution: goreleaser-pro
|
distribution: goreleaser-pro
|
||||||
version: latest
|
version: latest
|
||||||
args: release --clean
|
args: ${{ steps.setup.outputs.args }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GH_RELEASER_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GH_RELEASER_TOKEN }}
|
||||||
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||||
@@ -46,3 +92,4 @@ jobs:
|
|||||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
|
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
|
||||||
|
CLOUDSMITH_TOKEN: ${{ secrets.CLOUDSMITH_TOKEN }}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Update Version
|
name: Update Version and Release
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -10,30 +10,33 @@ permissions:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
run-tests:
|
|
||||||
name: "Run tests"
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: "1.23"
|
|
||||||
check-latest: true
|
|
||||||
- name: Run tests
|
|
||||||
run: make test
|
|
||||||
|
|
||||||
bump-version:
|
bump-version:
|
||||||
needs: [run-tests]
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: "Bump Version"
|
name: "Bump Version"
|
||||||
if: ${{ !startsWith(github.event.head_commit.message, 'bump:') }}
|
if: ${{ !startsWith(github.event.head_commit.message, 'bump:') }}
|
||||||
|
outputs:
|
||||||
|
new_tag: ${{ steps.bump.outputs.new_tag }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Create bump and changelog
|
- name: Create bump and changelog
|
||||||
|
id: bump
|
||||||
uses: commitizen-tools/commitizen-action@master
|
uses: commitizen-tools/commitizen-action@master
|
||||||
with:
|
with:
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
increment: "PATCH"
|
increment: "PATCH"
|
||||||
|
|
||||||
|
trigger-release:
|
||||||
|
needs: [bump-version]
|
||||||
|
if: needs.bump-version.outputs.new_tag != ''
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Trigger release workflow
|
||||||
|
uses: peter-evans/repository-dispatch@v2
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
event-type: trigger-release
|
||||||
|
client-payload: '{"tag": "${{ needs.bump-version.outputs.new_tag }}"}'
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
# Binaries
|
# Binaries
|
||||||
|
no
|
||||||
.data
|
.data
|
||||||
schemas
|
schemas
|
||||||
*.db
|
*.db
|
||||||
@@ -41,6 +42,7 @@ go.work.sum
|
|||||||
# Environment files
|
# Environment files
|
||||||
.env
|
.env
|
||||||
**/*.env
|
**/*.env
|
||||||
|
**/sonr.log
|
||||||
|
|
||||||
|
|
||||||
# Terraform
|
# Terraform
|
||||||
@@ -60,6 +62,7 @@ override.tf.json
|
|||||||
.terraformrc
|
.terraformrc
|
||||||
terraform.rc
|
terraform.rc
|
||||||
|
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.tmp/
|
.tmp/
|
||||||
@@ -93,4 +96,8 @@ sonr.wiki
|
|||||||
!buf.lock
|
!buf.lock
|
||||||
|
|
||||||
.air.toml
|
.air.toml
|
||||||
|
mprocs.yaml
|
||||||
|
mprocs.log
|
||||||
|
tools-stamp
|
||||||
|
sonr.log
|
||||||
|
|
||||||
|
|||||||
+143
-26
@@ -4,24 +4,161 @@ project_name: sonr
|
|||||||
|
|
||||||
builds:
|
builds:
|
||||||
- id: sonr
|
- id: sonr
|
||||||
goos: [linux, darwin]
|
|
||||||
goarch: [amd64, arm64]
|
|
||||||
main: ./cmd/sonrd
|
main: ./cmd/sonrd
|
||||||
binary: sonrd
|
binary: sonrd
|
||||||
builder: go
|
builder: go
|
||||||
gobinary: go
|
gobinary: go
|
||||||
command: build
|
mod_timestamp: "{{ .CommitTimestamp }}"
|
||||||
|
goos:
|
||||||
|
- linux
|
||||||
|
- darwin
|
||||||
|
goarch:
|
||||||
|
- amd64
|
||||||
|
- arm64
|
||||||
|
goamd64:
|
||||||
|
- v1
|
||||||
|
flags:
|
||||||
|
- -mod=readonly
|
||||||
|
- -trimpath
|
||||||
ldflags:
|
ldflags:
|
||||||
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}
|
- -X github.com/cosmos/cosmos-sdk/version.Name=sonr
|
||||||
|
- -X github.com/cosmos/cosmos-sdk/version.AppName=sonrd
|
||||||
|
- -X github.com/cosmos/cosmos-sdk/version.Version={{.Version}}
|
||||||
|
- -X github.com/cosmos/cosmos-sdk/version.Commit={{.Commit}}
|
||||||
|
- -X "github.com/cosmos/cosmos-sdk/version.BuildTags=netgo,ledger"
|
||||||
|
tags:
|
||||||
|
- netgo
|
||||||
|
- ledger
|
||||||
|
|
||||||
|
- id: hway
|
||||||
|
main: ./cmd/hway
|
||||||
|
binary: hway
|
||||||
|
builder: go
|
||||||
|
gobinary: go
|
||||||
|
goos:
|
||||||
|
- linux
|
||||||
|
- darwin
|
||||||
|
goarch:
|
||||||
|
- amd64
|
||||||
|
- arm64
|
||||||
|
mod_timestamp: "{{ .CommitTimestamp }}"
|
||||||
|
flags:
|
||||||
|
- -mod=readonly
|
||||||
|
- -trimpath
|
||||||
|
goamd64:
|
||||||
|
- v1
|
||||||
|
tags:
|
||||||
|
- netgo
|
||||||
|
ldflags:
|
||||||
|
- -X main.version={{.Version}}
|
||||||
|
- -X main.commit={{.Commit}}
|
||||||
|
- -X main.date={{.Date}}
|
||||||
archives:
|
archives:
|
||||||
- id: sonr
|
- id: sonr
|
||||||
builds: [sonr]
|
builds: [sonr]
|
||||||
name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ with .Arm }}v{{ . }}{{ end }}{{ with .Mips }}_{{ . }}{{ end }}{{ if not (eq .Amd64 "v1") }}{{ .Amd64 }}{{ end }}'
|
name_template: >-
|
||||||
|
sonr_{{ .Version }}_
|
||||||
|
{{- title .Os }}_{{- if eq .Arch "amd64" }}x86_64
|
||||||
|
{{- else if eq .Arch "386" }}i386
|
||||||
|
{{- else }}{{ .Arch }}{{ end }}
|
||||||
format: tar.gz
|
format: tar.gz
|
||||||
files:
|
files:
|
||||||
- src: README*
|
- src: README*
|
||||||
- src: CHANGELOG*
|
wrap_in_directory: true
|
||||||
|
|
||||||
|
- id: hway
|
||||||
|
builds: [hway]
|
||||||
|
name_template: >-
|
||||||
|
hway_{{ .Version }}_
|
||||||
|
{{- title .Os }}_{{- if eq .Arch "amd64" }}x86_64
|
||||||
|
{{- else if eq .Arch "386" }}i386
|
||||||
|
{{- else }}{{ .Arch }}{{ end }}
|
||||||
|
format: tar.gz
|
||||||
|
files:
|
||||||
|
- src: README*
|
||||||
|
wrap_in_directory: true
|
||||||
|
|
||||||
|
nfpms:
|
||||||
|
- id: hway
|
||||||
|
package_name: hway
|
||||||
|
file_name_template: "{{ .ConventionalFileName }}"
|
||||||
|
builds: [hway]
|
||||||
|
vendor: Sonr
|
||||||
|
homepage: "https://onsonr.dev"
|
||||||
|
maintainer: "Sonr <support@onsonr.dev>"
|
||||||
|
description: "Sonr Highway is a decentralized, permissionless, and censorship-resistant identity network proxy."
|
||||||
|
license: "Apache 2.0"
|
||||||
|
formats:
|
||||||
|
- rpm
|
||||||
|
- deb
|
||||||
|
- apk
|
||||||
|
dependencies:
|
||||||
|
- ipfs
|
||||||
|
contents:
|
||||||
|
- src: README*
|
||||||
|
dst: /usr/share/doc/hway
|
||||||
|
bindir: /usr/bin
|
||||||
|
section: net
|
||||||
|
priority: optional
|
||||||
|
# Add these lines to match build config
|
||||||
|
|
||||||
|
- id: sonr
|
||||||
|
package_name: sonrd
|
||||||
|
file_name_template: "{{ .ConventionalFileName }}"
|
||||||
|
builds: [sonr]
|
||||||
|
vendor: Sonr
|
||||||
|
homepage: "https://onsonr.dev"
|
||||||
|
maintainer: "Sonr <support@onsonr.dev>"
|
||||||
|
description: "Sonr is a decentralized, permissionless, and censorship-resistant identity network."
|
||||||
|
license: "Apache 2.0"
|
||||||
|
formats:
|
||||||
|
- rpm
|
||||||
|
- deb
|
||||||
|
- apk
|
||||||
|
dependencies:
|
||||||
|
- ipfs
|
||||||
|
contents:
|
||||||
|
- src: README*
|
||||||
|
dst: /usr/share/doc/sonrd
|
||||||
|
bindir: /usr/bin
|
||||||
|
section: net
|
||||||
|
priority: optional
|
||||||
|
# Add these lines to match build config
|
||||||
|
|
||||||
|
brews:
|
||||||
|
- name: hway
|
||||||
|
ids: [hway]
|
||||||
|
commit_author:
|
||||||
|
name: goreleaserbot
|
||||||
|
email: bot@goreleaser.com
|
||||||
|
directory: Formula
|
||||||
|
caveats: "Run a local hway node and access it with the hway proxy"
|
||||||
|
homepage: "https://onsonr.dev"
|
||||||
|
description: "Sonr is a decentralized, permissionless, and censorship-resistant identity network."
|
||||||
|
dependencies:
|
||||||
|
- name: ipfs
|
||||||
|
repository:
|
||||||
|
owner: onsonr
|
||||||
|
name: homebrew-tap
|
||||||
|
branch: master
|
||||||
|
token: "{{ .Env.GITHUB_PERSONAL_AUTH_TOKEN }}"
|
||||||
|
|
||||||
|
- name: sonr
|
||||||
|
ids: [sonr]
|
||||||
|
commit_author:
|
||||||
|
name: goreleaserbot
|
||||||
|
email: bot@goreleaser.com
|
||||||
|
directory: Formula
|
||||||
|
caveats: "Run a local sonr node and access it with the hway proxy"
|
||||||
|
homepage: "https://onsonr.dev"
|
||||||
|
description: "Sonr is a decentralized, permissionless, and censorship-resistant identity network."
|
||||||
|
dependencies:
|
||||||
|
- name: ipfs
|
||||||
|
repository:
|
||||||
|
owner: onsonr
|
||||||
|
name: homebrew-tap
|
||||||
|
branch: master
|
||||||
|
token: "{{ .Env.GITHUB_PERSONAL_AUTH_TOKEN }}"
|
||||||
|
|
||||||
release:
|
release:
|
||||||
github:
|
github:
|
||||||
@@ -32,27 +169,7 @@ release:
|
|||||||
replace_existing_draft: true
|
replace_existing_draft: true
|
||||||
replace_existing_artifacts: true
|
replace_existing_artifacts: true
|
||||||
extra_files:
|
extra_files:
|
||||||
- glob: ./CHANGELOG*
|
|
||||||
- glob: ./README*
|
- glob: ./README*
|
||||||
- glob: ./LICENSE*
|
|
||||||
|
|
||||||
brews:
|
|
||||||
- name: sonr
|
|
||||||
ids: [sonr]
|
|
||||||
commit_author:
|
|
||||||
name: goreleaserbot
|
|
||||||
email: bot@goreleaser.com
|
|
||||||
directory: Formula
|
|
||||||
caveats: "Run a local sonr node and access it with the hway proxy"
|
|
||||||
homepage: "https://sonr.io/"
|
|
||||||
description: "Sonr is a decentralized, permissionless, and censorship-resistant identity network."
|
|
||||||
dependencies:
|
|
||||||
- name: ipfs
|
|
||||||
repository:
|
|
||||||
owner: onsonr
|
|
||||||
name: homebrew-tap
|
|
||||||
branch: master
|
|
||||||
token: "{{ .Env.GITHUB_PERSONAL_AUTH_TOKEN }}"
|
|
||||||
|
|
||||||
announce:
|
announce:
|
||||||
telegram:
|
telegram:
|
||||||
|
|||||||
@@ -8,9 +8,14 @@ SDK_PACK := $(shell go list -m github.com/cosmos/cosmos-sdk | sed 's/ /\@/g')
|
|||||||
BINDIR ?= $(GOPATH)/bin
|
BINDIR ?= $(GOPATH)/bin
|
||||||
SIMAPP = ./app
|
SIMAPP = ./app
|
||||||
|
|
||||||
|
PC_PORT_NUM=42069
|
||||||
|
PC_LOG_FILE=./sonr.log
|
||||||
|
PC_SOCKET_PATH=/tmp/sonr-net.sock
|
||||||
|
|
||||||
# for dockerized protobuf tools
|
# for dockerized protobuf tools
|
||||||
DOCKER := $(shell which docker)
|
DOCKER := $(shell which docker)
|
||||||
HTTPS_GIT := github.com/onsonr/sonr.git
|
HTTPS_GIT := github.com/onsonr/sonr.git
|
||||||
|
PROCESS_COMPOSE := $(shell which process-compose)
|
||||||
|
|
||||||
export GO111MODULE = on
|
export GO111MODULE = on
|
||||||
|
|
||||||
@@ -115,13 +120,17 @@ clean:
|
|||||||
rm -rf .aider*
|
rm -rf .aider*
|
||||||
rm -rf static
|
rm -rf static
|
||||||
rm -rf .out
|
rm -rf .out
|
||||||
rm -rf build
|
|
||||||
rm -rf hway.db
|
rm -rf hway.db
|
||||||
rm -rf snapcraft-local.yaml build/
|
rm -rf snapcraft-local.yaml build/
|
||||||
|
rm -rf build
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -rf vendor/
|
rm -rf vendor/
|
||||||
|
|
||||||
|
init-env:
|
||||||
|
@echo "Installing process-compose"
|
||||||
|
sh scripts/init_env.sh
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
### Testing
|
### Testing
|
||||||
|
|
||||||
@@ -175,7 +184,6 @@ format: format-tools
|
|||||||
|
|
||||||
mod-tidy:
|
mod-tidy:
|
||||||
go mod tidy
|
go mod tidy
|
||||||
cd interchaintest && go mod tidy
|
|
||||||
|
|
||||||
.PHONY: format-tools lint format mod-tidy
|
.PHONY: format-tools lint format mod-tidy
|
||||||
|
|
||||||
@@ -298,51 +306,69 @@ sh-testnet: mod-tidy
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
### generation ###
|
### generation ###
|
||||||
###############################################################################
|
###############################################################################
|
||||||
.PHONY: pkl-gen tailwind-gen templ-gen
|
.PHONY: gen-pkl gen-templ gen-sqlc
|
||||||
|
|
||||||
pkl-gen:
|
gen-pkl: init-env
|
||||||
go install github.com/apple/pkl-go/cmd/pkl-gen-go@latest
|
pkl-gen-go pkl/sonr.orm/UCAN.pkl
|
||||||
pkl-gen-go pkl/sonr.motr/ATN.pkl
|
pkl-gen-go pkl/sonr.orm/Models.pkl
|
||||||
pkl-gen-go pkl/sonr.hway/Env.pkl
|
pkl-gen-go pkl/sonr.net/Hway.pkl
|
||||||
pkl-gen-go pkl/sonr.motr/DWN.pkl
|
pkl-gen-go pkl/sonr.net/Motr.pkl
|
||||||
pkl-gen-go pkl/sonr.hway/ORM.pkl
|
|
||||||
|
|
||||||
templ-gen:
|
gen-sqlc: init-env
|
||||||
@go install github.com/a-h/templ/cmd/templ@latest
|
@cd internal/database && sqlc generate
|
||||||
templ generate
|
|
||||||
|
gen-templ: init-env
|
||||||
|
@templ generate
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
### custom builds ###
|
### custom builds ###
|
||||||
###############################################################################
|
###############################################################################
|
||||||
.PHONY: motr-build hway-build hway-serve
|
.PHONY: build-motr build-hway logs-hway logs-sonr
|
||||||
|
|
||||||
motr-build:
|
build-motr:
|
||||||
GOOS=js GOARCH=wasm go build -o static/wasm/app.wasm ./cmd/motr/main.go
|
GOOS=js GOARCH=wasm go build -o static/wasm/app.wasm ./cmd/motr/main.go
|
||||||
|
|
||||||
hway-build: templ-gen
|
build-hway: gen-templ
|
||||||
go build -o build/hway ./cmd/hway/main.go
|
go build -o build/hway ./cmd/hway
|
||||||
|
|
||||||
hway-serve: hway-build
|
logs-hway: init-env
|
||||||
./build/hway
|
bin/process-compose process logs hway --port $(PC_PORT_NUM) --follow
|
||||||
|
|
||||||
|
logs-sonr: init-env
|
||||||
|
bin/process-compose process logs sonr --port $(PC_PORT_NUM) --follow
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
### Network Start/Stop ###
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
.PHONY: deploy start start-tui start-uds stop stop-uds restart status
|
||||||
|
|
||||||
|
start: build-hway init-env
|
||||||
|
bin/process-compose up --port $(PC_PORT_NUM) --log-file $(PC_LOG_FILE) -f deploy/process-compose.yaml
|
||||||
|
|
||||||
|
start-uds: build-hway init-env
|
||||||
|
bin/process-compose up --use-uds --unix-socket $(PC_SOCKET_PATH) --log-file $(PC_LOG_FILE) --detached -f deploy/process-compose.yaml
|
||||||
|
|
||||||
|
stop: init-env
|
||||||
|
bin/process-compose down --port $(PC_PORT_NUM)
|
||||||
|
|
||||||
|
stop-uds: init-env
|
||||||
|
bin/process-compose down --use-uds --unix-socket $(PC_SOCKET_PATH)
|
||||||
|
|
||||||
|
status: init-env
|
||||||
|
bin/process-compose project state --port $(PC_PORT_NUM)
|
||||||
|
|
||||||
|
status-uds: init-env
|
||||||
|
bin/process-compose project state --use-uds --unix-socket $(PC_SOCKET_PATH)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
### help ###
|
### help ###
|
||||||
###############################################################################
|
###############################################################################
|
||||||
.PHONY: deploy-buf deploy-pkl
|
|
||||||
|
|
||||||
deploy-buf:
|
deploy:
|
||||||
cd ./proto && bunx buf dep update && bunx buf build && bunx buf push
|
cd ./proto && bunx buf dep update && bunx buf build && bunx buf push
|
||||||
|
|
||||||
deploy-pkl:
|
|
||||||
sh ./.github/scripts/upload_cdn.sh
|
sh ./.github/scripts/upload_cdn.sh
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
### help ###
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "Usage: make <target>"
|
@echo "Usage: make <target>"
|
||||||
@echo ""
|
@echo ""
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/onsonr/sonr/pkg/common"
|
||||||
|
"github.com/onsonr/sonr/pkg/gateway"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Command line flags
|
||||||
|
var (
|
||||||
|
servePort int // Gateway http entry point (default 3000)
|
||||||
|
chainID string // Current chain ID (default sonr-testnet-1)
|
||||||
|
ipfsGatewayURL string // IPFS gateway URL (default localhost:8080)
|
||||||
|
sonrAPIURL string // Sonr API URL (default localhost:1317)
|
||||||
|
sonrGrpcURL string // Sonr gRPC URL (default localhost:9090)
|
||||||
|
sonrRPCURL string // Sonr RPC URL (default localhost:26657)
|
||||||
|
|
||||||
|
psqlHost string // PostgresSQL Host Flag
|
||||||
|
psqlUser string // PostgresSQL User Flag
|
||||||
|
psqlPass string // PostgresSQL Password Flag
|
||||||
|
psqlDB string // PostgresSQL Database Flag
|
||||||
|
)
|
||||||
|
|
||||||
|
func rootCmd() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "hway",
|
||||||
|
Short: "Sonr DID gateway",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
env, err := loadEnvImplFromArgs(args)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
ipc, err := common.NewIPFS()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
e, err := gateway.New(env, ipc)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := e.Start(fmt.Sprintf(":%d", env.GetServePort())); err != http.ErrServerClosed {
|
||||||
|
log.Fatal(err)
|
||||||
|
os.Exit(1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cmd.Flags().IntVar(&servePort, "serve-port", 3000, "Port to serve the gateway on")
|
||||||
|
cmd.Flags().StringVar(&chainID, "chain-id", "sonr-testnet-1", "Chain ID")
|
||||||
|
cmd.Flags().StringVar(&ipfsGatewayURL, "ipfs-gateway-url", "localhost:8080", "IPFS gateway URL")
|
||||||
|
cmd.Flags().StringVar(&sonrAPIURL, "sonr-api-url", "localhost:1317", "Sonr API URL")
|
||||||
|
cmd.Flags().StringVar(&sonrGrpcURL, "sonr-grpc-url", "localhost:9090", "Sonr gRPC URL")
|
||||||
|
cmd.Flags().StringVar(&sonrRPCURL, "sonr-rpc-url", "localhost:26657", "Sonr RPC URL")
|
||||||
|
cmd.Flags().StringVar(&psqlHost, "psql-host", "", "PostgresSQL Host")
|
||||||
|
cmd.Flags().StringVar(&psqlUser, "psql-user", "", "PostgresSQL User")
|
||||||
|
cmd.Flags().StringVar(&psqlPass, "psql-pass", "", "PostgresSQL Password")
|
||||||
|
cmd.Flags().StringVar(&psqlDB, "psql-db", "", "PostgresSQL Database")
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatPsqlDSN() string {
|
||||||
|
if psqlHost == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=disable", psqlHost, psqlUser, psqlPass, psqlDB)
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
amends "https://pkl.sh/sonr.hway/0.0.3/Env.pkl"
|
|
||||||
+23
-44
@@ -3,56 +3,35 @@ package main
|
|||||||
import (
|
import (
|
||||||
_ "embed"
|
_ "embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
config "github.com/onsonr/sonr/internal/config/hway"
|
||||||
"github.com/labstack/echo/v4/middleware"
|
|
||||||
"github.com/onsonr/sonr/crypto/ucan"
|
|
||||||
"github.com/onsonr/sonr/pkg/common/ipfs"
|
|
||||||
"github.com/onsonr/sonr/pkg/common/producer"
|
|
||||||
"github.com/onsonr/sonr/pkg/gateway"
|
|
||||||
"github.com/onsonr/sonr/pkg/gateway/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed config.pkl
|
|
||||||
var configBz []byte
|
|
||||||
|
|
||||||
func loadConfig() (config.Env, error) {
|
|
||||||
return config.LoadFromBytes(configBz)
|
|
||||||
}
|
|
||||||
|
|
||||||
// setupServer sets up the server
|
|
||||||
func setupServer(env config.Env) (*echo.Echo, error) {
|
|
||||||
ipc, err := ipfs.NewClient()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
e := echo.New()
|
|
||||||
e.IPExtractor = echo.ExtractIPDirect()
|
|
||||||
e.Use(middleware.Logger())
|
|
||||||
e.Use(middleware.Recover())
|
|
||||||
e.Use(producer.Middleware(ipc, ucan.ServicePermissions))
|
|
||||||
gateway.RegisterRoutes(e, env)
|
|
||||||
return e, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// main is the entry point for the application
|
// main is the entry point for the application
|
||||||
func main() {
|
func main() {
|
||||||
env, err := loadConfig()
|
cmd := rootCmd()
|
||||||
if err != nil {
|
if err := cmd.Execute(); err != nil {
|
||||||
panic(err)
|
fmt.Println(err)
|
||||||
}
|
|
||||||
|
|
||||||
e, err := setupServer(env)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := e.Start(fmt.Sprintf(":%d", env.GetServePort())); err != http.ErrServerClosed {
|
|
||||||
log.Fatal(err)
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadEnvImplFromArgs(args []string) (config.Hway, error) {
|
||||||
|
cmd := rootCmd()
|
||||||
|
if err := cmd.ParseFlags(args); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
env := &config.HwayImpl{
|
||||||
|
ServePort: servePort,
|
||||||
|
ChainId: chainID,
|
||||||
|
IpfsGatewayUrl: ipfsGatewayURL,
|
||||||
|
SonrApiUrl: sonrAPIURL,
|
||||||
|
SonrGrpcUrl: sonrGrpcURL,
|
||||||
|
SonrRpcUrl: sonrRPCURL,
|
||||||
|
PsqlDSN: formatPsqlDSN(),
|
||||||
|
}
|
||||||
|
return env, nil
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-11
@@ -8,15 +8,14 @@ import (
|
|||||||
"syscall/js"
|
"syscall/js"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/onsonr/sonr/cmd/motr/internal"
|
"github.com/onsonr/sonr/pkg/vault/routes"
|
||||||
"github.com/onsonr/sonr/pkg/common/controller"
|
"github.com/onsonr/sonr/cmd/motr/wasm"
|
||||||
"github.com/onsonr/sonr/pkg/vault"
|
"github.com/onsonr/sonr/internal/config/motr"
|
||||||
"github.com/onsonr/sonr/pkg/vault/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
env *types.Environment
|
env *motr.Environment
|
||||||
config *types.Config
|
config *motr.Config
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -28,7 +27,7 @@ func simulateTx(this js.Value, args []js.Value) interface{} {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func processConfig(this js.Value, args []js.Value) interface{} {
|
func syncData(this js.Value, args []js.Value) interface{} {
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -45,11 +44,11 @@ func main() {
|
|||||||
// Load dwn config
|
// Load dwn config
|
||||||
js.Global().Set("broadcastTx", js.FuncOf(broadcastTx))
|
js.Global().Set("broadcastTx", js.FuncOf(broadcastTx))
|
||||||
js.Global().Set("simulateTx", js.FuncOf(simulateTx))
|
js.Global().Set("simulateTx", js.FuncOf(simulateTx))
|
||||||
js.Global().Set("processConfig", js.FuncOf(processConfig))
|
js.Global().Set("syncData", js.FuncOf(syncData))
|
||||||
|
|
||||||
e := echo.New()
|
e := echo.New()
|
||||||
e.Use(internal.WasmContextMiddleware)
|
e.Use(wasm.ContextMiddleware)
|
||||||
e.Use(controller.Middleware(nil))
|
// e.Use(controller.Middleware(nil))
|
||||||
vault.RegisterRoutes(e, config)
|
vault.RegisterRoutes(e, config)
|
||||||
internal.ServeFetch(e)
|
wasm.ServeFetch(e)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//go:build js && wasm
|
//go:build js && wasm
|
||||||
// +build js,wasm
|
// +build js,wasm
|
||||||
|
|
||||||
package internal
|
package wasm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -30,7 +30,7 @@ var (
|
|||||||
jsWasmHTTP = jsGlobal.Get("wasmhttp")
|
jsWasmHTTP = jsGlobal.Get("wasmhttp")
|
||||||
)
|
)
|
||||||
|
|
||||||
// serveFetch serves HTTP requests with optimized handler management
|
// ServeFetch serves HTTP requests with optimized handler management
|
||||||
func ServeFetch(handler http.Handler) func() {
|
func ServeFetch(handler http.Handler) func() {
|
||||||
h := handler
|
h := handler
|
||||||
if h == nil {
|
if h == nil {
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//go:build js && wasm
|
//go:build js && wasm
|
||||||
// +build js,wasm
|
// +build js,wasm
|
||||||
|
|
||||||
package internal
|
package wasm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
func WasmContextMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
|
func ContextMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(c echo.Context) error {
|
return func(c echo.Context) error {
|
||||||
// Extract WASM context from headers
|
// Extract WASM context from headers
|
||||||
if wasmCtx := c.Request().Header.Get("X-Wasm-Context"); wasmCtx != "" {
|
if wasmCtx := c.Request().Header.Get("X-Wasm-Context"); wasmCtx != "" {
|
||||||
+1
-1
@@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rootCmd := NewRootCmd()
|
rootCmd := NewRootCmd()
|
||||||
|
rootCmd.AddCommand(newPklInitCmd())
|
||||||
if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil {
|
if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil {
|
||||||
log.NewLogger(rootCmd.OutOrStderr()).Error("failure when running app", "err", err)
|
log.NewLogger(rootCmd.OutOrStderr()).Error("failure when running app", "err", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/apple/pkl-go/pkl"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var configDir string
|
||||||
|
|
||||||
|
func newPklInitCmd() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "init-pkl",
|
||||||
|
Short: "Initialize the Sonrd configuration using PKL",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
ctx := context.Background()
|
||||||
|
evaluator, err := pkl.NewEvaluator(ctx, pkl.PreconfiguredOptions)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer evaluator.Close()
|
||||||
|
|
||||||
|
appPath := formatConfigPath(cmd, "app.toml")
|
||||||
|
configPath := formatConfigPath(cmd, "config.toml")
|
||||||
|
|
||||||
|
// Create app.toml
|
||||||
|
if err := createAppToml(evaluator, appPath); err != nil {
|
||||||
|
cmd.PrintErrf("Failed to create app.toml: %v\n", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmd.Printf("Successfully created %s\n", appPath)
|
||||||
|
|
||||||
|
// Create config.toml
|
||||||
|
if err := createConfigToml(evaluator, configPath); err != nil {
|
||||||
|
cmd.PrintErrf("Failed to create config.toml: %v\n", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmd.Printf("Successfully created %s\n", configPath)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cmd.Flags().StringVar(&configDir, "config-dir", "~/.sonr/config", "Path to where pkl files should be output")
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func createAppToml(evaluator pkl.Evaluator, path string) error {
|
||||||
|
appSource := pkl.UriSource("https://pkl.sh/sonr.chain/0.0.2/App.pkl")
|
||||||
|
res, err := evaluator.EvaluateOutputText(context.Background(), appSource)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Printf("res: %s", res)
|
||||||
|
return writeConfigFile(path, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createConfigToml(evaluator pkl.Evaluator, path string) error {
|
||||||
|
configSource := pkl.UriSource("https://pkl.sh/sonr.chain/0.0.2/Config.pkl")
|
||||||
|
res, err := evaluator.EvaluateOutputText(context.Background(), configSource)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Printf("res: %s", res)
|
||||||
|
return writeConfigFile(path, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatConfigPath(cmd *cobra.Command, fileName string) string {
|
||||||
|
configDir := cmd.Flag("config-dir").Value.String()
|
||||||
|
// Expand home directory if needed
|
||||||
|
if configDir[:2] == "~/" {
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err == nil {
|
||||||
|
configDir = filepath.Join(home, configDir[2:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filepath.Join(configDir, fileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeConfigFile(path string, content string) error {
|
||||||
|
// Create the directory path if it doesn't exist
|
||||||
|
dir := filepath.Dir(path)
|
||||||
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if file already exists
|
||||||
|
if _, err := os.Stat(path); err == nil {
|
||||||
|
// File exists, create backup
|
||||||
|
backupPath := path + ".backup"
|
||||||
|
if err := os.Rename(path, backupPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the new config file
|
||||||
|
return os.WriteFile(path, []byte(content), 0o644)
|
||||||
|
}
|
||||||
@@ -601,11 +601,11 @@ func (p *PointBls12377G1) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12377G1) MarshalJSON() ([]byte, error) {
|
func (p *PointBls12377G1) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJson(p)
|
return pointMarshalJSON(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12377G1) UnmarshalJSON(input []byte) error {
|
func (p *PointBls12377G1) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJson(input)
|
pt, err := pointUnmarshalJSON(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -874,11 +874,11 @@ func (p *PointBls12377G2) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12377G2) MarshalJSON() ([]byte, error) {
|
func (p *PointBls12377G2) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJson(p)
|
return pointMarshalJSON(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12377G2) UnmarshalJSON(input []byte) error {
|
func (p *PointBls12377G2) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJson(input)
|
pt, err := pointUnmarshalJSON(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -573,11 +573,11 @@ func (p *PointBls12381G1) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12381G1) MarshalJSON() ([]byte, error) {
|
func (p *PointBls12381G1) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJson(p)
|
return pointMarshalJSON(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12381G1) UnmarshalJSON(input []byte) error {
|
func (p *PointBls12381G1) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJson(input)
|
pt, err := pointUnmarshalJSON(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -823,11 +823,11 @@ func (p *PointBls12381G2) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12381G2) MarshalJSON() ([]byte, error) {
|
func (p *PointBls12381G2) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJson(p)
|
return pointMarshalJSON(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12381G2) UnmarshalJSON(input []byte) error {
|
func (p *PointBls12381G2) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJson(input)
|
pt, err := pointUnmarshalJSON(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -336,14 +336,14 @@ func pointUnmarshalText(input []byte) (Point, error) {
|
|||||||
return curve.Point.FromAffineCompressed(buffer)
|
return curve.Point.FromAffineCompressed(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func pointMarshalJson(point Point) ([]byte, error) {
|
func pointMarshalJSON(point Point) ([]byte, error) {
|
||||||
m := make(map[string]string, 2)
|
m := make(map[string]string, 2)
|
||||||
m["type"] = point.CurveName()
|
m["type"] = point.CurveName()
|
||||||
m["value"] = hex.EncodeToString(point.ToAffineCompressed())
|
m["value"] = hex.EncodeToString(point.ToAffineCompressed())
|
||||||
return json.Marshal(m)
|
return json.Marshal(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func pointUnmarshalJson(input []byte) (Point, error) {
|
func pointUnmarshalJSON(input []byte) (Point, error) {
|
||||||
var m map[string]string
|
var m map[string]string
|
||||||
|
|
||||||
err := json.Unmarshal(input, &m)
|
err := json.Unmarshal(input, &m)
|
||||||
|
|||||||
@@ -682,11 +682,11 @@ func (p *PointEd25519) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointEd25519) MarshalJSON() ([]byte, error) {
|
func (p *PointEd25519) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJson(p)
|
return pointMarshalJSON(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointEd25519) UnmarshalJSON(input []byte) error {
|
func (p *PointEd25519) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJson(input)
|
pt, err := pointUnmarshalJSON(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -653,11 +653,11 @@ func (p *PointK256) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointK256) MarshalJSON() ([]byte, error) {
|
func (p *PointK256) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJson(p)
|
return pointMarshalJSON(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointK256) UnmarshalJSON(input []byte) error {
|
func (p *PointK256) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJson(input)
|
pt, err := pointUnmarshalJSON(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -701,11 +701,11 @@ func (p *BenchPointP256) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *BenchPointP256) MarshalJSON() ([]byte, error) {
|
func (p *BenchPointP256) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJson(p)
|
return pointMarshalJSON(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *BenchPointP256) UnmarshalJSON(input []byte) error {
|
func (p *BenchPointP256) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJson(input)
|
pt, err := pointUnmarshalJSON(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -651,11 +651,11 @@ func (p *PointP256) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointP256) MarshalJSON() ([]byte, error) {
|
func (p *PointP256) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJson(p)
|
return pointMarshalJSON(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointP256) UnmarshalJSON(input []byte) error {
|
func (p *PointP256) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJson(input)
|
pt, err := pointUnmarshalJSON(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -669,11 +669,11 @@ func (p *PointPallas) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointPallas) MarshalJSON() ([]byte, error) {
|
func (p *PointPallas) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJson(p)
|
return pointMarshalJSON(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointPallas) UnmarshalJSON(input []byte) error {
|
func (p *PointPallas) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJson(input)
|
pt, err := pointUnmarshalJSON(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,162 @@
|
|||||||
|
package keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ed25519"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/x509"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/libp2p/go-libp2p/core/crypto"
|
||||||
|
mb "github.com/multiformats/go-multibase"
|
||||||
|
varint "github.com/multiformats/go-varint"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// KeyPrefix indicates a decentralized identifier that uses the key method
|
||||||
|
KeyPrefix = "did:key"
|
||||||
|
// MulticodecKindRSAPubKey rsa-x509-pub https://github.com/multiformats/multicodec/pull/226
|
||||||
|
MulticodecKindRSAPubKey = 0x1205
|
||||||
|
// MulticodecKindEd25519PubKey ed25519-pub
|
||||||
|
MulticodecKindEd25519PubKey = 0xed
|
||||||
|
// MulticodecKindSecp256k1PubKey secp256k1-pub
|
||||||
|
MulticodecKindSecp256k1PubKey = 0x1206
|
||||||
|
)
|
||||||
|
|
||||||
|
// DID is a DID:key identifier
|
||||||
|
type DID struct {
|
||||||
|
crypto.PubKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDID constructs an Identifier from a public key
|
||||||
|
func NewDID(pub crypto.PubKey) (DID, error) {
|
||||||
|
switch pub.Type() {
|
||||||
|
case crypto.Ed25519, crypto.RSA, crypto.Secp256k1:
|
||||||
|
return DID{PubKey: pub}, nil
|
||||||
|
default:
|
||||||
|
return DID{}, fmt.Errorf("unsupported key type: %s", pub.Type())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFromPubKey constructs an Identifier from a public key
|
||||||
|
func NewFromPubKey(pub PubKey) DID {
|
||||||
|
return DID{PubKey: pub}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MulticodecType indicates the type for this multicodec
|
||||||
|
func (id DID) MulticodecType() uint64 {
|
||||||
|
switch id.Type() {
|
||||||
|
case crypto.RSA:
|
||||||
|
return MulticodecKindRSAPubKey
|
||||||
|
case crypto.Ed25519:
|
||||||
|
return MulticodecKindEd25519PubKey
|
||||||
|
case crypto.Secp256k1:
|
||||||
|
return MulticodecKindSecp256k1PubKey
|
||||||
|
default:
|
||||||
|
panic("unexpected crypto type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns this did:key formatted as a string
|
||||||
|
func (id DID) String() string {
|
||||||
|
raw, err := id.Raw()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
t := id.MulticodecType()
|
||||||
|
size := varint.UvarintSize(t)
|
||||||
|
data := make([]byte, size+len(raw))
|
||||||
|
n := varint.PutUvarint(data, t)
|
||||||
|
copy(data[n:], raw)
|
||||||
|
|
||||||
|
b58BKeyStr, err := mb.Encode(mb.Base58BTC, data)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s:%s", KeyPrefix, b58BKeyStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifyKey returns the backing implementation for a public key, one of:
|
||||||
|
// *rsa.PublicKey, ed25519.PublicKey
|
||||||
|
func (id DID) VerifyKey() (interface{}, error) {
|
||||||
|
rawPubBytes, err := id.Raw()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch id.Type() {
|
||||||
|
case crypto.RSA:
|
||||||
|
verifyKeyiface, err := x509.ParsePKIXPublicKey(rawPubBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
verifyKey, ok := verifyKeyiface.(*rsa.PublicKey)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("public key is not an RSA key. got type: %T", verifyKeyiface)
|
||||||
|
}
|
||||||
|
return verifyKey, nil
|
||||||
|
case crypto.Ed25519:
|
||||||
|
return ed25519.PublicKey(rawPubBytes), nil
|
||||||
|
case crypto.Secp256k1:
|
||||||
|
// Handle both compressed and uncompressed Secp256k1 public keys
|
||||||
|
if len(rawPubBytes) == 65 || len(rawPubBytes) == 33 {
|
||||||
|
return rawPubBytes, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("invalid Secp256k1 public key length: %d", len(rawPubBytes))
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unrecognized Public Key type: %s", id.Type())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse turns a string into a key method ID
|
||||||
|
func Parse(keystr string) (DID, error) {
|
||||||
|
var id DID
|
||||||
|
if !strings.HasPrefix(keystr, KeyPrefix) {
|
||||||
|
return id, fmt.Errorf("decentralized identifier is not a 'key' type")
|
||||||
|
}
|
||||||
|
|
||||||
|
keystr = strings.TrimPrefix(keystr, KeyPrefix+":")
|
||||||
|
|
||||||
|
enc, data, err := mb.Decode(keystr)
|
||||||
|
if err != nil {
|
||||||
|
return id, fmt.Errorf("decoding multibase: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if enc != mb.Base58BTC {
|
||||||
|
return id, fmt.Errorf("unexpected multibase encoding: %s", mb.EncodingToStr[enc])
|
||||||
|
}
|
||||||
|
|
||||||
|
keyType, n, err := varint.FromUvarint(data)
|
||||||
|
if err != nil {
|
||||||
|
return id, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch keyType {
|
||||||
|
case MulticodecKindRSAPubKey:
|
||||||
|
pub, err := crypto.UnmarshalRsaPublicKey(data[n:])
|
||||||
|
if err != nil {
|
||||||
|
return id, err
|
||||||
|
}
|
||||||
|
return DID{pub}, nil
|
||||||
|
case MulticodecKindEd25519PubKey:
|
||||||
|
pub, err := crypto.UnmarshalEd25519PublicKey(data[n:])
|
||||||
|
if err != nil {
|
||||||
|
return id, err
|
||||||
|
}
|
||||||
|
return DID{pub}, nil
|
||||||
|
case MulticodecKindSecp256k1PubKey:
|
||||||
|
// Handle both compressed and uncompressed formats
|
||||||
|
keyData := data[n:]
|
||||||
|
if len(keyData) != 33 && len(keyData) != 65 {
|
||||||
|
return id, fmt.Errorf("invalid Secp256k1 public key length: %d", len(keyData))
|
||||||
|
}
|
||||||
|
pub, err := crypto.UnmarshalSecp256k1PublicKey(keyData)
|
||||||
|
if err != nil {
|
||||||
|
return id, fmt.Errorf("failed to unmarshal Secp256k1 key: %w", err)
|
||||||
|
}
|
||||||
|
return DID{pub}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return id, fmt.Errorf("unrecognized key type multicodec prefix: %x", data[0])
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package keys
|
||||||
|
|
||||||
|
type DIDMethod string
|
||||||
|
|
||||||
|
const (
|
||||||
|
DIDMethodKey DIDMethod = "key"
|
||||||
|
DIDMethodSonr DIDMethod = "sonr"
|
||||||
|
DIDMehthodBitcoin DIDMethod = "btcr"
|
||||||
|
DIDMethodEthereum DIDMethod = "ethr"
|
||||||
|
DIDMethodCbor DIDMethod = "cbor"
|
||||||
|
DIDMethodCID DIDMethod = "cid"
|
||||||
|
DIDMethodIPFS DIDMethod = "ipfs"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (d DIDMethod) String() string {
|
||||||
|
return string(d)
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
package parsers
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package parsers
|
||||||
|
|
||||||
|
type CosmosPrefix string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ATOMPrefix CosmosPrefix = "cosmos"
|
||||||
|
AXELARPrefix CosmosPrefix = "axelar"
|
||||||
|
EVMOSPrefix CosmosPrefix = "evmos"
|
||||||
|
OSMOPrefix CosmosPrefix = "osmo"
|
||||||
|
SONRPrefix CosmosPrefix = "idx"
|
||||||
|
STARSPrefix CosmosPrefix = "stars"
|
||||||
|
)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
package parsers
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
package parsers
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package didkey
|
package parsers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
@@ -23,23 +23,23 @@ const (
|
|||||||
MulticodecKindSecp256k1PubKey = 0x1206
|
MulticodecKindSecp256k1PubKey = 0x1206
|
||||||
)
|
)
|
||||||
|
|
||||||
// ID is a DID:key identifier
|
// DIDKey is a DID:key identifier
|
||||||
type ID struct {
|
type DIDKey struct {
|
||||||
crypto.PubKey
|
crypto.PubKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewID constructs an Identifier from a public key
|
// NewKeyDID constructs an Identifier from a public key
|
||||||
func NewID(pub crypto.PubKey) (ID, error) {
|
func NewKeyDID(pub crypto.PubKey) (DIDKey, error) {
|
||||||
switch pub.Type() {
|
switch pub.Type() {
|
||||||
case crypto.Ed25519, crypto.RSA, crypto.Secp256k1:
|
case crypto.Ed25519, crypto.RSA, crypto.Secp256k1:
|
||||||
return ID{PubKey: pub}, nil
|
return DIDKey{PubKey: pub}, nil
|
||||||
default:
|
default:
|
||||||
return ID{}, fmt.Errorf("unsupported key type: %s", pub.Type())
|
return DIDKey{}, fmt.Errorf("unsupported key type: %s", pub.Type())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MulticodecType indicates the type for this multicodec
|
// MulticodecType indicates the type for this multicodec
|
||||||
func (id ID) MulticodecType() uint64 {
|
func (id DIDKey) MulticodecType() uint64 {
|
||||||
switch id.Type() {
|
switch id.Type() {
|
||||||
case crypto.RSA:
|
case crypto.RSA:
|
||||||
return MulticodecKindRSAPubKey
|
return MulticodecKindRSAPubKey
|
||||||
@@ -53,7 +53,7 @@ func (id ID) MulticodecType() uint64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// String returns this did:key formatted as a string
|
// String returns this did:key formatted as a string
|
||||||
func (id ID) String() string {
|
func (id DIDKey) String() string {
|
||||||
raw, err := id.Raw()
|
raw, err := id.Raw()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
@@ -75,7 +75,7 @@ func (id ID) String() string {
|
|||||||
|
|
||||||
// VerifyKey returns the backing implementation for a public key, one of:
|
// VerifyKey returns the backing implementation for a public key, one of:
|
||||||
// *rsa.PublicKey, ed25519.PublicKey
|
// *rsa.PublicKey, ed25519.PublicKey
|
||||||
func (id ID) VerifyKey() (interface{}, error) {
|
func (id DIDKey) VerifyKey() (interface{}, error) {
|
||||||
rawPubBytes, err := id.PubKey.Raw()
|
rawPubBytes, err := id.PubKey.Raw()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -100,13 +100,13 @@ func (id ID) VerifyKey() (interface{}, error) {
|
|||||||
}
|
}
|
||||||
return nil, fmt.Errorf("invalid Secp256k1 public key length: %d", len(rawPubBytes))
|
return nil, fmt.Errorf("invalid Secp256k1 public key length: %d", len(rawPubBytes))
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unrecognized Public Key type: %s", id.PubKey.Type())
|
return nil, fmt.Errorf("unrecognized Public Key type: %s", id.Type())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse turns a string into a key method ID
|
// Parse turns a string into a key method ID
|
||||||
func Parse(keystr string) (ID, error) {
|
func Parse(keystr string) (DIDKey, error) {
|
||||||
var id ID
|
var id DIDKey
|
||||||
if !strings.HasPrefix(keystr, KeyPrefix) {
|
if !strings.HasPrefix(keystr, KeyPrefix) {
|
||||||
return id, fmt.Errorf("decentralized identifier is not a 'key' type")
|
return id, fmt.Errorf("decentralized identifier is not a 'key' type")
|
||||||
}
|
}
|
||||||
@@ -133,13 +133,13 @@ func Parse(keystr string) (ID, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return id, err
|
return id, err
|
||||||
}
|
}
|
||||||
return ID{pub}, nil
|
return DIDKey{pub}, nil
|
||||||
case MulticodecKindEd25519PubKey:
|
case MulticodecKindEd25519PubKey:
|
||||||
pub, err := crypto.UnmarshalEd25519PublicKey(data[n:])
|
pub, err := crypto.UnmarshalEd25519PublicKey(data[n:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return id, err
|
return id, err
|
||||||
}
|
}
|
||||||
return ID{pub}, nil
|
return DIDKey{pub}, nil
|
||||||
case MulticodecKindSecp256k1PubKey:
|
case MulticodecKindSecp256k1PubKey:
|
||||||
// Handle both compressed and uncompressed formats
|
// Handle both compressed and uncompressed formats
|
||||||
keyData := data[n:]
|
keyData := data[n:]
|
||||||
@@ -150,7 +150,7 @@ func Parse(keystr string) (ID, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return id, fmt.Errorf("failed to unmarshal Secp256k1 key: %w", err)
|
return id, fmt.Errorf("failed to unmarshal Secp256k1 key: %w", err)
|
||||||
}
|
}
|
||||||
return ID{pub}, nil
|
return DIDKey{pub}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return id, fmt.Errorf("unrecognized key type multicodec prefix: %x", data[0])
|
return id, fmt.Errorf("unrecognized key type multicodec prefix: %x", data[0])
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
package parsers
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
package parsers
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"encoding/hex"
|
||||||
|
|
||||||
|
p2pcrypto "github.com/libp2p/go-libp2p/core/crypto"
|
||||||
|
p2ppb "github.com/libp2p/go-libp2p/core/crypto/pb"
|
||||||
|
"github.com/onsonr/sonr/crypto/core/curves"
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PubKey interface {
|
||||||
|
Bytes() []byte
|
||||||
|
Raw() ([]byte, error)
|
||||||
|
Equals(b p2pcrypto.Key) bool
|
||||||
|
Type() p2ppb.KeyType
|
||||||
|
Hex() string
|
||||||
|
Verify(msg []byte, sig []byte) (bool, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type pubKey struct {
|
||||||
|
publicPoint curves.Point
|
||||||
|
method string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPubKey(pk curves.Point) PubKey {
|
||||||
|
return &pubKey{
|
||||||
|
publicPoint: pk,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p pubKey) Bytes() []byte {
|
||||||
|
return p.publicPoint.ToAffineCompressed()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p pubKey) Raw() ([]byte, error) {
|
||||||
|
return p.publicPoint.ToAffineCompressed(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p pubKey) Equals(b p2pcrypto.Key) bool {
|
||||||
|
if b == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
apbz, err := b.Raw()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
bbz, err := p.Raw()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return bytes.Equal(apbz, bbz)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p pubKey) Hex() string {
|
||||||
|
return hex.EncodeToString(p.publicPoint.ToAffineCompressed())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p pubKey) Type() p2ppb.KeyType {
|
||||||
|
return p2ppb.KeyType_Secp256k1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p pubKey) Verify(data []byte, sigBz []byte) (bool, error) {
|
||||||
|
sig, err := deserializeSignature(sigBz)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
pp, err := getEcdsaPoint(p.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
pk := &ecdsa.PublicKey{
|
||||||
|
Curve: pp.Curve,
|
||||||
|
X: pp.X,
|
||||||
|
Y: pp.Y,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash the message using SHA3-256
|
||||||
|
hash := sha3.New256()
|
||||||
|
hash.Write(data)
|
||||||
|
digest := hash.Sum(nil)
|
||||||
|
|
||||||
|
return ecdsa.Verify(pk, digest, sig.R, sig.S), nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/onsonr/sonr/crypto/core/curves"
|
||||||
|
)
|
||||||
|
|
||||||
|
// getEcdsaPoint builds an elliptic curve point from a compressed byte slice
|
||||||
|
func getEcdsaPoint(pubKey []byte) (*curves.EcPoint, error) {
|
||||||
|
crv := curves.K256()
|
||||||
|
x := new(big.Int).SetBytes(pubKey[1:33])
|
||||||
|
y := new(big.Int).SetBytes(pubKey[33:])
|
||||||
|
ecCurve, err := crv.ToEllipticCurve()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error converting curve: %v", err)
|
||||||
|
}
|
||||||
|
return &curves.EcPoint{X: x, Y: y, Curve: ecCurve}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeSecp256k1Signature serializes an ECDSA signature into a byte slice
|
||||||
|
func serializeSignature(sig *curves.EcdsaSignature) ([]byte, error) {
|
||||||
|
rBytes := sig.R.Bytes()
|
||||||
|
sBytes := sig.S.Bytes()
|
||||||
|
|
||||||
|
sigBytes := make([]byte, 66) // V (1 byte) + R (32 bytes) + S (32 bytes)
|
||||||
|
sigBytes[0] = byte(sig.V)
|
||||||
|
copy(sigBytes[33-len(rBytes):33], rBytes)
|
||||||
|
copy(sigBytes[66-len(sBytes):66], sBytes)
|
||||||
|
return sigBytes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeserializeSecp256k1Signature deserializes an ECDSA signature from a byte slice
|
||||||
|
func deserializeSignature(sigBytes []byte) (*curves.EcdsaSignature, error) {
|
||||||
|
if len(sigBytes) != 66 {
|
||||||
|
return nil, errors.New("malformed signature: not the correct size")
|
||||||
|
}
|
||||||
|
sig := &curves.EcdsaSignature{
|
||||||
|
V: int(sigBytes[0]),
|
||||||
|
R: new(big.Int).SetBytes(sigBytes[1:33]),
|
||||||
|
S: new(big.Int).SetBytes(sigBytes[33:66]),
|
||||||
|
}
|
||||||
|
return sig, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package mpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/onsonr/sonr/crypto/core/curves"
|
||||||
|
"github.com/onsonr/sonr/crypto/core/protocol"
|
||||||
|
"github.com/onsonr/sonr/crypto/keys"
|
||||||
|
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1/dkg"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ╭───────────────────────────────────────────────────────────╮
|
||||||
|
// │ Exported Generics │
|
||||||
|
// ╰───────────────────────────────────────────────────────────╯
|
||||||
|
|
||||||
|
type (
|
||||||
|
AliceOut *dkg.AliceOutput
|
||||||
|
BobOut *dkg.BobOutput
|
||||||
|
Point curves.Point
|
||||||
|
Role string // Role is the type for the role
|
||||||
|
Message *protocol.Message // Message is the protocol.Message that is used for MPC
|
||||||
|
Signature *curves.EcdsaSignature // Signature is the type for the signature
|
||||||
|
RefreshFunc interface{ protocol.Iterator } // RefreshFunc is the type for the refresh function
|
||||||
|
SignFunc interface{ protocol.Iterator } // SignFunc is the type for the sign function
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
RoleVal = "validator"
|
||||||
|
RoleUser = "user"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Enclave defines the interface for key management operations
|
||||||
|
type Enclave interface {
|
||||||
|
Address() string // Address returns the Sonr address of the keyEnclave
|
||||||
|
DID() keys.DID // DID returns the DID of the keyEnclave
|
||||||
|
Export(key []byte) ([]byte, error) // Export returns encrypted enclave data
|
||||||
|
Import(data []byte, key []byte) error // Import decrypts and loads enclave data
|
||||||
|
IsValid() bool // IsValid returns true if the keyEnclave is valid
|
||||||
|
PubKey() keys.PubKey // PubKey returns the public key of the keyEnclave
|
||||||
|
Refresh() (Enclave, error) // Refresh returns a new keyEnclave
|
||||||
|
Serialize() ([]byte, error) // Serialize returns the serialized keyEnclave
|
||||||
|
Sign(data []byte) ([]byte, error) // Sign returns the signature of the data
|
||||||
|
Verify(data []byte, sig []byte) (bool, error) // Verify returns true if the signature is valid
|
||||||
|
}
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
package mpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func randNonce() []byte {
|
||||||
|
nonce := make([]byte, 12)
|
||||||
|
rand.Read(nonce)
|
||||||
|
return nonce
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKeyShareGeneration(t *testing.T) {
|
||||||
|
t.Run("Generate Valid Enclave", func(t *testing.T) {
|
||||||
|
nonce := randNonce()
|
||||||
|
// Generate enclave
|
||||||
|
enclave, err := GenEnclave(nonce)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, enclave)
|
||||||
|
|
||||||
|
// Validate enclave contents
|
||||||
|
assert.True(t, enclave.IsValid())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Export and Import", func(t *testing.T) {
|
||||||
|
nonce := randNonce()
|
||||||
|
// Generate original enclave
|
||||||
|
original, err := GenEnclave(nonce)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Test key for encryption/decryption (32 bytes)
|
||||||
|
testKey := []byte("test-key-12345678-test-key-123456")
|
||||||
|
|
||||||
|
// Test Export/Import
|
||||||
|
t.Run("Full Enclave", func(t *testing.T) {
|
||||||
|
// Export enclave
|
||||||
|
data, err := original.Export(testKey)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEmpty(t, data)
|
||||||
|
|
||||||
|
// Create new empty enclave
|
||||||
|
newEnclave, err := GenEnclave(nonce)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Import enclave
|
||||||
|
err = newEnclave.Import(data, testKey)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Verify the imported enclave works by signing
|
||||||
|
testData := []byte("test message")
|
||||||
|
sig, err := newEnclave.Sign(testData)
|
||||||
|
require.NoError(t, err)
|
||||||
|
valid, err := newEnclave.Verify(testData, sig)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, valid)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Test Invalid Key
|
||||||
|
t.Run("Invalid Key", func(t *testing.T) {
|
||||||
|
data, err := original.Export(testKey)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
wrongKey := []byte("wrong-key-12345678")
|
||||||
|
err = original.Import(data, wrongKey)
|
||||||
|
assert.Error(t, err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnclaveOperations(t *testing.T) {
|
||||||
|
t.Run("Signing and Verification", func(t *testing.T) {
|
||||||
|
nonce := randNonce()
|
||||||
|
// Generate valid enclave
|
||||||
|
enclave, err := GenEnclave(nonce)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Test signing
|
||||||
|
testData := []byte("test message")
|
||||||
|
signature, err := enclave.Sign(testData)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, signature)
|
||||||
|
|
||||||
|
// Verify the signature
|
||||||
|
valid, err := enclave.Verify(testData, signature)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.True(t, valid)
|
||||||
|
|
||||||
|
// Test invalid data verification
|
||||||
|
invalidData := []byte("wrong message")
|
||||||
|
valid, err = enclave.Verify(invalidData, signature)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.False(t, valid)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Address and Public Key", func(t *testing.T) {
|
||||||
|
nonce := randNonce()
|
||||||
|
enclave, err := GenEnclave(nonce)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Test Address
|
||||||
|
addr := enclave.Address()
|
||||||
|
assert.NotEmpty(t, addr)
|
||||||
|
assert.True(t, strings.HasPrefix(addr, "idx"))
|
||||||
|
|
||||||
|
// Test Public Key
|
||||||
|
pubKey := enclave.PubKey()
|
||||||
|
assert.NotNil(t, pubKey)
|
||||||
|
assert.NotEmpty(t, pubKey.Bytes())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Refresh Operation", func(t *testing.T) {
|
||||||
|
nonce := randNonce()
|
||||||
|
enclave, err := GenEnclave(nonce)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Test refresh
|
||||||
|
refreshedEnclave, err := enclave.Refresh()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, refreshedEnclave)
|
||||||
|
|
||||||
|
// Verify refreshed enclave is valid
|
||||||
|
assert.True(t, refreshedEnclave.IsValid())
|
||||||
|
|
||||||
|
// Verify it maintains the same address
|
||||||
|
assert.Equal(t, enclave.Address(), refreshedEnclave.Address())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnclaveSerialization(t *testing.T) {
|
||||||
|
t.Run("Marshal and Unmarshal", func(t *testing.T) {
|
||||||
|
nonce := randNonce()
|
||||||
|
// Generate original enclave
|
||||||
|
original, err := GenEnclave(nonce)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, original)
|
||||||
|
|
||||||
|
// Marshal
|
||||||
|
keyclave, ok := original.(*keyEnclave)
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
data, err := keyclave.Serialize()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEmpty(t, data)
|
||||||
|
|
||||||
|
// Unmarshal
|
||||||
|
restored := &keyEnclave{}
|
||||||
|
err = restored.Unmarshal(data)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Verify restored enclave
|
||||||
|
assert.Equal(t, keyclave.Addr, restored.Addr)
|
||||||
|
assert.True(t, keyclave.PubPoint.Equal(restored.PubPoint))
|
||||||
|
assert.True(t, restored.IsValid())
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,179 @@
|
|||||||
|
package mpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/onsonr/sonr/crypto/core/curves"
|
||||||
|
"github.com/onsonr/sonr/crypto/keys"
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
|
)
|
||||||
|
|
||||||
|
// keyEnclave implements the Enclave interface
|
||||||
|
type keyEnclave struct {
|
||||||
|
// Serialized fields
|
||||||
|
Addr string `json:"address"`
|
||||||
|
PubPoint curves.Point `json:"-"`
|
||||||
|
PubBytes []byte `json:"pub_key"`
|
||||||
|
ValShare Message `json:"val_share"`
|
||||||
|
UserShare Message `json:"user_share"`
|
||||||
|
|
||||||
|
// Extra fields
|
||||||
|
nonce []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func newEnclave(valShare, userShare Message, nonce []byte) (Enclave, error) {
|
||||||
|
pubPoint, err := getAlicePubPoint(valShare)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
addr, err := computeSonrAddr(pubPoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &keyEnclave{
|
||||||
|
Addr: addr,
|
||||||
|
PubPoint: pubPoint,
|
||||||
|
ValShare: valShare,
|
||||||
|
UserShare: userShare,
|
||||||
|
nonce: nonce,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Address returns the Sonr address of the keyEnclave
|
||||||
|
func (k *keyEnclave) Address() string {
|
||||||
|
return k.Addr
|
||||||
|
}
|
||||||
|
|
||||||
|
// DID returns the DID of the keyEnclave
|
||||||
|
func (k *keyEnclave) DID() keys.DID {
|
||||||
|
return keys.NewFromPubKey(k.PubKey())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export returns encrypted enclave data
|
||||||
|
func (k *keyEnclave) Export(key []byte) ([]byte, error) {
|
||||||
|
data, err := k.Serialize()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to serialize enclave: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
hashedKey := hashKey(key)
|
||||||
|
block, err := aes.NewCipher(hashedKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
aesgcm, err := cipher.NewGCM(block)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return aesgcm.Seal(nil, k.nonce, data, nil), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import decrypts and loads enclave data
|
||||||
|
func (k *keyEnclave) Import(data []byte, key []byte) error {
|
||||||
|
hashedKey := hashKey(key)
|
||||||
|
block, err := aes.NewCipher(hashedKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
aesgcm, err := cipher.NewGCM(block)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
decrypted, err := aesgcm.Open(nil, k.nonce, data, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return k.Unmarshal(decrypted)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsValid returns true if the keyEnclave is valid
|
||||||
|
func (k *keyEnclave) IsValid() bool {
|
||||||
|
return k.PubPoint != nil && k.ValShare != nil && k.UserShare != nil && k.Addr != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// PubKey returns the public key of the keyEnclave
|
||||||
|
func (k *keyEnclave) PubKey() keys.PubKey {
|
||||||
|
return keys.NewPubKey(k.PubPoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh returns a new keyEnclave
|
||||||
|
func (k *keyEnclave) Refresh() (Enclave, error) {
|
||||||
|
refreshFuncVal, err := valRefreshFunc(k)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
refreshFuncUser, err := userRefreshFunc(k)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ExecuteRefresh(refreshFuncVal, refreshFuncUser, k.nonce)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign returns the signature of the data
|
||||||
|
func (k *keyEnclave) Sign(data []byte) ([]byte, error) {
|
||||||
|
userSign, err := userSignFunc(k, data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
valSign, err := valSignFunc(k, data)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ExecuteSigning(valSign, userSign)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify returns true if the signature is valid
|
||||||
|
func (k *keyEnclave) Verify(data []byte, sig []byte) (bool, error) {
|
||||||
|
edSig, err := deserializeSignature(sig)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
ePub, err := getEcdsaPoint(k.PubPoint.ToAffineUncompressed())
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
pk := &ecdsa.PublicKey{
|
||||||
|
Curve: ePub.Curve,
|
||||||
|
X: ePub.X,
|
||||||
|
Y: ePub.Y,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash the message using SHA3-256
|
||||||
|
hash := sha3.New256()
|
||||||
|
hash.Write(data)
|
||||||
|
digest := hash.Sum(nil)
|
||||||
|
|
||||||
|
return ecdsa.Verify(pk, digest, edSig.R, edSig.S), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal returns the JSON encoding of keyEnclave
|
||||||
|
func (k *keyEnclave) Serialize() ([]byte, error) {
|
||||||
|
// Store compressed public point bytes before marshaling
|
||||||
|
k.PubBytes = k.PubPoint.ToAffineCompressed()
|
||||||
|
return json.Marshal(k)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal parses the JSON-encoded data and stores the result
|
||||||
|
func (k *keyEnclave) Unmarshal(data []byte) error {
|
||||||
|
if err := json.Unmarshal(data, k); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Reconstruct Point from bytes
|
||||||
|
curve := curves.K256()
|
||||||
|
point, err := curve.NewIdentityPoint().FromAffineCompressed(k.PubBytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
k.PubPoint = point
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
package mpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
genericecdsa "crypto/ecdsa"
|
|
||||||
"fmt"
|
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/types/bech32"
|
|
||||||
"github.com/onsonr/sonr/crypto/core/curves"
|
|
||||||
"github.com/onsonr/sonr/crypto/core/protocol"
|
|
||||||
"golang.org/x/crypto/sha3"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
ExportedKeyset = []byte
|
|
||||||
)
|
|
||||||
|
|
||||||
type Keyset interface {
|
|
||||||
Val() *ValKeyshare
|
|
||||||
ValJSON() string
|
|
||||||
User() *UserKeyshare
|
|
||||||
UserJSON() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type keyset struct {
|
|
||||||
val *ValKeyshare
|
|
||||||
user *UserKeyshare
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k keyset) Val() *ValKeyshare {
|
|
||||||
return k.val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k keyset) User() *UserKeyshare {
|
|
||||||
return k.user
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k keyset) ValJSON() string {
|
|
||||||
return k.val.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k keyset) UserJSON() string {
|
|
||||||
return k.user.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func ComputeIssuerDID(pk []byte) (string, string, error) {
|
|
||||||
addr, err := ComputeSonrAddr(pk)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("did:sonr:%s", addr), addr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ComputeSonrAddr(pk []byte) (string, error) {
|
|
||||||
sonrAddr, err := bech32.ConvertAndEncode("idx", pk)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return sonrAddr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// For DKG bob starts first. For refresh and sign, Alice starts first.
|
|
||||||
func RunProtocol(firstParty protocol.Iterator, secondParty protocol.Iterator) (error, error) {
|
|
||||||
var (
|
|
||||||
message *protocol.Message
|
|
||||||
aErr error
|
|
||||||
bErr error
|
|
||||||
)
|
|
||||||
|
|
||||||
for aErr != protocol.ErrProtocolFinished || bErr != protocol.ErrProtocolFinished {
|
|
||||||
// Crank each protocol forward one iteration
|
|
||||||
message, bErr = firstParty.Next(message)
|
|
||||||
if bErr != nil && bErr != protocol.ErrProtocolFinished {
|
|
||||||
return nil, bErr
|
|
||||||
}
|
|
||||||
|
|
||||||
message, aErr = secondParty.Next(message)
|
|
||||||
if aErr != nil && aErr != protocol.ErrProtocolFinished {
|
|
||||||
return aErr, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return aErr, bErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// ComputeEcPoint builds an elliptic curve point from a compressed byte slice
|
|
||||||
func ComputeEcPoint(pubKey []byte) (*curves.EcPoint, error) {
|
|
||||||
crv := curves.K256()
|
|
||||||
x := new(big.Int).SetBytes(pubKey[1:33])
|
|
||||||
y := new(big.Int).SetBytes(pubKey[33:])
|
|
||||||
ecCurve, err := crv.ToEllipticCurve()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error converting curve: %v", err)
|
|
||||||
}
|
|
||||||
return &curves.EcPoint{X: x, Y: y, Curve: ecCurve}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ComputeEcdsaPublicKey(pubKey []byte) (*genericecdsa.PublicKey, error) {
|
|
||||||
pk, err := ComputeEcPoint(pubKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &genericecdsa.PublicKey{
|
|
||||||
Curve: pk.Curve,
|
|
||||||
X: pk.X,
|
|
||||||
Y: pk.Y,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// VerifySignature verifies the signature of a message
|
|
||||||
func VerifySignature(pk []byte, msg []byte, sig []byte) (bool, error) {
|
|
||||||
pp, err := ComputeEcPoint(pk)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
sigEd, err := DeserializeSignature(sig)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
hash := sha3.New256()
|
|
||||||
_, err = hash.Write(msg)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
digest := hash.Sum(nil)
|
|
||||||
return curves.VerifyEcdsa(pp, digest[:], sigEd), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkIteratedErrors(aErr, bErr error) error {
|
|
||||||
if aErr == protocol.ErrProtocolFinished && bErr == protocol.ErrProtocolFinished {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if aErr != protocol.ErrProtocolFinished {
|
|
||||||
return aErr
|
|
||||||
}
|
|
||||||
if bErr != protocol.ErrProtocolFinished {
|
|
||||||
return bErr
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
package mpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ecdsa"
|
|
||||||
|
|
||||||
"github.com/onsonr/sonr/crypto/core/protocol"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Keyshare represents the common interface for both validator and user keyshares
|
|
||||||
type Keyshare interface {
|
|
||||||
GetPayloads() map[string][]byte
|
|
||||||
GetMetadata() map[string]string
|
|
||||||
GetPublicKey() []byte
|
|
||||||
GetProtocol() string
|
|
||||||
GetRole() int32
|
|
||||||
GetVersion() uint32
|
|
||||||
ECDSAPublicKey() (*ecdsa.PublicKey, error)
|
|
||||||
ExtractMessage() *protocol.Message
|
|
||||||
RefreshFunc() (RefreshFunc, error)
|
|
||||||
SignFunc(msg []byte) (SignFunc, error)
|
|
||||||
Marshal() (string, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// BaseKeyshare contains common fields and methods for both validator and user keyshares
|
|
||||||
type BaseKeyshare struct {
|
|
||||||
Message *protocol.Message `json:"message"`
|
|
||||||
Role int `json:"role"`
|
|
||||||
UncompressedPubKey []byte `json:"public_key"`
|
|
||||||
CompressedPubKey []byte `json:"compressed_public_key"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BaseKeyshare) GetPayloads() map[string][]byte {
|
|
||||||
return b.Message.Payloads
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BaseKeyshare) GetMetadata() map[string]string {
|
|
||||||
return b.Message.Metadata
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BaseKeyshare) GetPublicKey() []byte {
|
|
||||||
return b.UncompressedPubKey
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BaseKeyshare) GetProtocol() string {
|
|
||||||
return b.Message.Protocol
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BaseKeyshare) GetRole() int32 {
|
|
||||||
return int32(b.Role)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BaseKeyshare) GetVersion() uint32 {
|
|
||||||
return uint32(b.Message.Version)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BaseKeyshare) ECDSAPublicKey() (*ecdsa.PublicKey, error) {
|
|
||||||
return ComputeEcdsaPublicKey(b.UncompressedPubKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BaseKeyshare) ExtractMessage() *protocol.Message {
|
|
||||||
return &protocol.Message{
|
|
||||||
Payloads: b.GetPayloads(),
|
|
||||||
Metadata: b.GetMetadata(),
|
|
||||||
Protocol: b.GetProtocol(),
|
|
||||||
Version: uint(b.GetVersion()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+31
-50
@@ -1,17 +1,13 @@
|
|||||||
package mpc
|
package mpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
|
||||||
"errors"
|
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"github.com/onsonr/sonr/crypto/core/curves"
|
"github.com/onsonr/sonr/crypto/core/curves"
|
||||||
"github.com/onsonr/sonr/crypto/core/protocol"
|
"github.com/onsonr/sonr/crypto/core/protocol"
|
||||||
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1"
|
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewKeyshareSource generates a new MPC keyshare
|
// GenEnclave generates a new MPC keyshare
|
||||||
func NewKeyset() (Keyset, error) {
|
func GenEnclave(nonce []byte) (Enclave, error) {
|
||||||
curve := curves.K256()
|
curve := curves.K256()
|
||||||
valKs := dklsv1.NewAliceDkg(curve, protocol.Version1)
|
valKs := dklsv1.NewAliceDkg(curve, protocol.Version1)
|
||||||
userKs := dklsv1.NewBobDkg(curve, protocol.Version1)
|
userKs := dklsv1.NewBobDkg(curve, protocol.Version1)
|
||||||
@@ -23,23 +19,15 @@ func NewKeyset() (Keyset, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
valShare, err := NewValKeyshare(valRes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
userRes, err := userKs.Result(protocol.Version1)
|
userRes, err := userKs.Result(protocol.Version1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
userShare, err := NewUserKeyshare(userRes)
|
return newEnclave(valRes, userRes, nonce)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return keyset{val: valShare, user: userShare}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecuteSigning runs the MPC signing protocol
|
// ExecuteSigning runs the MPC signing protocol
|
||||||
func ExecuteSigning(signFuncVal SignFunc, signFuncUser SignFunc) (Signature, error) {
|
func ExecuteSigning(signFuncVal SignFunc, signFuncUser SignFunc) ([]byte, error) {
|
||||||
aErr, bErr := RunProtocol(signFuncVal, signFuncUser)
|
aErr, bErr := RunProtocol(signFuncVal, signFuncUser)
|
||||||
if err := checkIteratedErrors(aErr, bErr); err != nil {
|
if err := checkIteratedErrors(aErr, bErr); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -48,11 +36,19 @@ func ExecuteSigning(signFuncVal SignFunc, signFuncUser SignFunc) (Signature, err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return dklsv1.DecodeSignature(out)
|
s, err := dklsv1.DecodeSignature(out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sig, err := serializeSignature(s)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return sig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecuteRefresh runs the MPC refresh protocol
|
// ExecuteRefresh runs the MPC refresh protocol
|
||||||
func ExecuteRefresh(refreshFuncVal RefreshFunc, refreshFuncUser RefreshFunc) (Keyset, error) {
|
func ExecuteRefresh(refreshFuncVal RefreshFunc, refreshFuncUser RefreshFunc, nonce []byte) (Enclave, error) {
|
||||||
aErr, bErr := RunProtocol(refreshFuncVal, refreshFuncUser)
|
aErr, bErr := RunProtocol(refreshFuncVal, refreshFuncUser)
|
||||||
if err := checkIteratedErrors(aErr, bErr); err != nil {
|
if err := checkIteratedErrors(aErr, bErr); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -61,47 +57,32 @@ func ExecuteRefresh(refreshFuncVal RefreshFunc, refreshFuncUser RefreshFunc) (Ke
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
valShare, err := NewValKeyshare(valRefreshResult)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
userRefreshResult, err := refreshFuncUser.Result(protocol.Version1)
|
userRefreshResult, err := refreshFuncUser.Result(protocol.Version1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
userShare, err := NewUserKeyshare(userRefreshResult)
|
return newEnclave(valRefreshResult, userRefreshResult, nonce)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return keyset{val: valShare, user: userShare}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SerializeSecp256k1Signature serializes an ECDSA signature into a byte slice
|
// For DKG bob starts first. For refresh and sign, Alice starts first.
|
||||||
func SerializeSignature(sig Signature) ([]byte, error) {
|
func RunProtocol(firstParty protocol.Iterator, secondParty protocol.Iterator) (error, error) {
|
||||||
rBytes := sig.R.Bytes()
|
var (
|
||||||
sBytes := sig.S.Bytes()
|
message *protocol.Message
|
||||||
|
aErr error
|
||||||
|
bErr error
|
||||||
|
)
|
||||||
|
|
||||||
sigBytes := make([]byte, 66) // V (1 byte) + R (32 bytes) + S (32 bytes)
|
for aErr != protocol.ErrProtocolFinished || bErr != protocol.ErrProtocolFinished {
|
||||||
sigBytes[0] = byte(sig.V)
|
// Crank each protocol forward one iteration
|
||||||
copy(sigBytes[33-len(rBytes):33], rBytes)
|
message, bErr = firstParty.Next(message)
|
||||||
copy(sigBytes[66-len(sBytes):66], sBytes)
|
if bErr != nil && bErr != protocol.ErrProtocolFinished {
|
||||||
return sigBytes, nil
|
return nil, bErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeserializeSecp256k1Signature deserializes an ECDSA signature from a byte slice
|
message, aErr = secondParty.Next(message)
|
||||||
func DeserializeSignature(sigBytes []byte) (Signature, error) {
|
if aErr != nil && aErr != protocol.ErrProtocolFinished {
|
||||||
if len(sigBytes) != 66 {
|
return aErr, nil
|
||||||
return nil, errors.New("malformed signature: not the correct size")
|
|
||||||
}
|
}
|
||||||
sig := &curves.EcdsaSignature{
|
|
||||||
V: int(sigBytes[0]),
|
|
||||||
R: new(big.Int).SetBytes(sigBytes[1:33]),
|
|
||||||
S: new(big.Int).SetBytes(sigBytes[33:66]),
|
|
||||||
}
|
}
|
||||||
return sig, nil
|
return aErr, bErr
|
||||||
}
|
|
||||||
|
|
||||||
// VerifyMPCSignature verifies an MPC signature
|
|
||||||
func VerifyMPCSignature(sig Signature, msg []byte, publicKey *ecdsa.PublicKey) bool {
|
|
||||||
return ecdsa.Verify(publicKey, msg, sig.R, sig.S)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,149 +0,0 @@
|
|||||||
package mpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/onsonr/sonr/crypto/core/curves"
|
|
||||||
"github.com/onsonr/sonr/crypto/core/protocol"
|
|
||||||
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1"
|
|
||||||
"golang.org/x/crypto/sha3"
|
|
||||||
)
|
|
||||||
|
|
||||||
var ErrInvalidKeyshareRole = errors.New("invalid keyshare role")
|
|
||||||
|
|
||||||
type Role int
|
|
||||||
|
|
||||||
const (
|
|
||||||
RoleUnknown Role = iota
|
|
||||||
RoleUser
|
|
||||||
RoleValidator
|
|
||||||
)
|
|
||||||
|
|
||||||
func (r Role) IsUser() bool {
|
|
||||||
return r == RoleUser
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r Role) IsValidator() bool {
|
|
||||||
return r == RoleValidator
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message is the protocol.Message that is used for MPC
|
|
||||||
type Message *protocol.Message
|
|
||||||
|
|
||||||
type Signature *curves.EcdsaSignature
|
|
||||||
|
|
||||||
// RefreshFunc is the type for the refresh function
|
|
||||||
type RefreshFunc interface {
|
|
||||||
protocol.Iterator
|
|
||||||
}
|
|
||||||
|
|
||||||
// SignFunc is the type for the sign function
|
|
||||||
type SignFunc interface {
|
|
||||||
protocol.Iterator
|
|
||||||
}
|
|
||||||
|
|
||||||
type ValKeyshare struct {
|
|
||||||
BaseKeyshare
|
|
||||||
encoded string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewValKeyshare(msg *protocol.Message) (*ValKeyshare, error) {
|
|
||||||
encoded, err := protocol.EncodeMessage(msg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
valShare, err := dklsv1.DecodeAliceDkgResult(msg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &ValKeyshare{
|
|
||||||
BaseKeyshare: BaseKeyshare{
|
|
||||||
Message: msg,
|
|
||||||
Role: 1,
|
|
||||||
UncompressedPubKey: valShare.PublicKey.ToAffineUncompressed(),
|
|
||||||
CompressedPubKey: valShare.PublicKey.ToAffineCompressed(),
|
|
||||||
},
|
|
||||||
encoded: encoded,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *ValKeyshare) RefreshFunc() (RefreshFunc, error) {
|
|
||||||
curve := curves.K256()
|
|
||||||
return dklsv1.NewAliceRefresh(curve, v.ExtractMessage(), protocol.Version1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *ValKeyshare) SignFunc(msg []byte) (SignFunc, error) {
|
|
||||||
curve := curves.K256()
|
|
||||||
return dklsv1.NewAliceSign(curve, sha3.New256(), msg, v.ExtractMessage(), protocol.Version1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *ValKeyshare) String() string {
|
|
||||||
return v.encoded
|
|
||||||
}
|
|
||||||
|
|
||||||
// PublicKey returns the uncompressed public key (65 bytes)
|
|
||||||
func (v *ValKeyshare) PublicKey() []byte {
|
|
||||||
return v.BaseKeyshare.UncompressedPubKey
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompressedPublicKey returns the compressed public key (33 bytes)
|
|
||||||
func (v *ValKeyshare) CompressedPublicKey() []byte {
|
|
||||||
return v.BaseKeyshare.CompressedPubKey
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserKeyshare struct {
|
|
||||||
BaseKeyshare
|
|
||||||
encoded string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewUserKeyshare(msg *protocol.Message) (*UserKeyshare, error) {
|
|
||||||
encoded, err := protocol.EncodeMessage(msg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
out, err := dklsv1.DecodeBobDkgResult(msg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &UserKeyshare{
|
|
||||||
BaseKeyshare: BaseKeyshare{
|
|
||||||
Message: msg,
|
|
||||||
Role: 2,
|
|
||||||
UncompressedPubKey: out.PublicKey.ToAffineUncompressed(),
|
|
||||||
CompressedPubKey: out.PublicKey.ToAffineCompressed(),
|
|
||||||
},
|
|
||||||
encoded: encoded,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *UserKeyshare) RefreshFunc() (RefreshFunc, error) {
|
|
||||||
curve := curves.K256()
|
|
||||||
return dklsv1.NewBobRefresh(curve, u.ExtractMessage(), protocol.Version1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *UserKeyshare) SignFunc(msg []byte) (SignFunc, error) {
|
|
||||||
curve := curves.K256()
|
|
||||||
return dklsv1.NewBobSign(curve, sha3.New256(), msg, u.ExtractMessage(), protocol.Version1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *UserKeyshare) String() string {
|
|
||||||
return u.encoded
|
|
||||||
}
|
|
||||||
|
|
||||||
// PublicKey returns the uncompressed public key (65 bytes)
|
|
||||||
func (u *UserKeyshare) PublicKey() []byte {
|
|
||||||
return u.BaseKeyshare.UncompressedPubKey
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompressedPublicKey returns the compressed public key (33 bytes)
|
|
||||||
func (u *UserKeyshare) CompressedPublicKey() []byte {
|
|
||||||
return u.BaseKeyshare.CompressedPubKey
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeMessage(m *protocol.Message) (string, error) {
|
|
||||||
return protocol.EncodeMessage(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeMessage(s string) (*protocol.Message, error) {
|
|
||||||
return protocol.DecodeMessage(s)
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package spec
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/sha256"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MPCSigningMethod implements the SigningMethod interface for MPC-based signing
|
||||||
|
type MPCSigningMethod struct {
|
||||||
|
Name string
|
||||||
|
ks ucanKeyshare
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewJWTSigningMethod creates a new MPC signing method with the given keyshare source
|
||||||
|
func NewJWTSigningMethod(name string, ks ucanKeyshare) *MPCSigningMethod {
|
||||||
|
return &MPCSigningMethod{
|
||||||
|
Name: name,
|
||||||
|
ks: ks,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alg returns the signing method's name
|
||||||
|
func (m *MPCSigningMethod) Alg() string {
|
||||||
|
return m.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify verifies the signature using the MPC public key
|
||||||
|
func (m *MPCSigningMethod) Verify(signingString, signature string, key interface{}) error {
|
||||||
|
// // Decode the signature
|
||||||
|
// sig, err := base64.RawURLEncoding.DecodeString(signature)
|
||||||
|
// if err != nil {
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Hash the signing string
|
||||||
|
// hasher := sha256.New()
|
||||||
|
// hasher.Write([]byte(signingString))
|
||||||
|
// digest := hasher.Sum(nil)
|
||||||
|
// valid, err := m.ks.valShare.PublicKey().Verify(digest, sig)
|
||||||
|
// if !valid || err != nil {
|
||||||
|
// return fmt.Errorf("invalid signature")
|
||||||
|
// }
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign signs the data using MPC
|
||||||
|
func (m *MPCSigningMethod) Sign(signingString string, key interface{}) (string, error) {
|
||||||
|
// Hash the signing string
|
||||||
|
hasher := sha256.New()
|
||||||
|
hasher.Write([]byte(signingString))
|
||||||
|
// digest := hasher.Sum(nil)
|
||||||
|
//
|
||||||
|
// // Create signing functions
|
||||||
|
// signFunc, err := m.ks.userShare.SignFunc(digest)
|
||||||
|
// if err != nil {
|
||||||
|
// return "", fmt.Errorf("failed to create sign function: %w", err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// valSignFunc, err := m.ks.valShare.SignFunc(digest)
|
||||||
|
// if err != nil {
|
||||||
|
// return "", fmt.Errorf("failed to create validator sign function: %w", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Run the signing protocol
|
||||||
|
// sig, err := mpc.ExecuteSigning(valSignFunc, signFunc)
|
||||||
|
// if err != nil {
|
||||||
|
// return "", fmt.Errorf("failed to run sign protocol: %w", err)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Encode the signature
|
||||||
|
// encoded := base64.RawURLEncoding.EncodeToString(sig)
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// Register the MPC signing method
|
||||||
|
jwt.RegisterSigningMethod("MPC256", func() jwt.SigningMethod {
|
||||||
|
return &MPCSigningMethod{
|
||||||
|
Name: "MPC256",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -5,9 +5,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/onsonr/sonr/crypto/mpc"
|
"github.com/onsonr/sonr/crypto/keys"
|
||||||
"github.com/onsonr/sonr/crypto/ucan"
|
"github.com/onsonr/sonr/crypto/ucan"
|
||||||
"github.com/onsonr/sonr/crypto/ucan/didkey"
|
|
||||||
"lukechampine.com/blake3"
|
"lukechampine.com/blake3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -23,21 +22,18 @@ type KeyshareSource interface {
|
|||||||
UCANParser() *ucan.TokenParser
|
UCANParser() *ucan.TokenParser
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSource(ks mpc.Keyset) (KeyshareSource, error) {
|
// func NewSource(ks mpc.KeyEnclave) (KeyshareSource, error) {
|
||||||
val := ks.Val()
|
// iss, addr, err := getIssuerDID(val.PublicKey())
|
||||||
user := ks.User()
|
// if err != nil {
|
||||||
iss, addr, err := ComputeIssuerDID(val.GetPublicKey())
|
// return nil, err
|
||||||
if err != nil {
|
// }
|
||||||
return nil, err
|
//
|
||||||
}
|
// return ucanKeyshare{
|
||||||
return ucanKeyshare{
|
// issuerDID: iss,
|
||||||
userShare: user,
|
// addr: addr,
|
||||||
valShare: val,
|
// }, nil
|
||||||
addr: addr,
|
// }
|
||||||
issuerDID: iss,
|
//
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Address returns the address of the keyshare
|
// Address returns the address of the keyshare
|
||||||
func (k ucanKeyshare) Address() string {
|
func (k ucanKeyshare) Address() string {
|
||||||
return k.addr
|
return k.addr
|
||||||
@@ -61,33 +57,32 @@ func (k ucanKeyshare) ChainCode() ([]byte, error) {
|
|||||||
|
|
||||||
// DefaultOriginToken returns a default token with the keyshare's issuer as the audience
|
// DefaultOriginToken returns a default token with the keyshare's issuer as the audience
|
||||||
func (k ucanKeyshare) OriginToken() (*Token, error) {
|
func (k ucanKeyshare) OriginToken() (*Token, error) {
|
||||||
att := ucan.NewSmartAccount(k.addr)
|
// att := ucan.NewSmartAccount(k.addr)
|
||||||
zero := time.Time{}
|
zero := time.Time{}
|
||||||
return k.NewOriginToken(k.issuerDID, att, nil, zero, zero)
|
// return k.NewOriginToken(k.issuerDID, att, nil, zero, zero)
|
||||||
|
return k.newToken(k.issuerDID, nil, nil, nil, zero, zero)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k ucanKeyshare) SignData(data []byte) ([]byte, error) {
|
func (k ucanKeyshare) SignData(data []byte) ([]byte, error) {
|
||||||
// Create signing functions
|
// // Create signing functions
|
||||||
signFunc, err := k.userShare.SignFunc(data)
|
// signFunc, err := k.userShare.SignFunc(data)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create sign function: %w", err)
|
// return nil, fmt.Errorf("failed to create sign function: %w", err)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
valSignFunc, err := k.valShare.SignFunc(data)
|
// valSignFunc, err := k.valShare.SignFunc(data)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create validator sign function: %w", err)
|
// return nil, fmt.Errorf("failed to create validator sign function: %w", err)
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Run the signing protocol
|
// Run the signing protocol
|
||||||
sig, err := mpc.ExecuteSigning(valSignFunc, signFunc)
|
// return mpc.ExecuteSigning(valSignFunc, signFunc)
|
||||||
if err != nil {
|
return nil, nil
|
||||||
return nil, fmt.Errorf("failed to run sign protocol: %w", err)
|
|
||||||
}
|
|
||||||
return mpc.SerializeSignature(sig)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k ucanKeyshare) VerifyData(data []byte, sig []byte) (bool, error) {
|
func (k ucanKeyshare) VerifyData(data []byte, sig []byte) (bool, error) {
|
||||||
return mpc.VerifySignature(k.userShare.PublicKey(), data, sig)
|
return false, nil
|
||||||
|
// return k.valShare.PublicKey().Verify(data, sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TokenParser returns a token parser that can be used to parse tokens
|
// TokenParser returns a token parser that can be used to parse tokens
|
||||||
@@ -107,7 +102,6 @@ func (k ucanKeyshare) UCANParser() *ucan.TokenParser {
|
|||||||
if key == ucan.CapKey {
|
if key == ucan.CapKey {
|
||||||
cap = val
|
cap = val
|
||||||
} else {
|
} else {
|
||||||
rsc = ucan.NewStringLengthResource(key, val)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,6 +121,6 @@ func (k ucanKeyshare) UCANParser() *ucan.TokenParser {
|
|||||||
type customDIDPubKeyResolver struct{}
|
type customDIDPubKeyResolver struct{}
|
||||||
|
|
||||||
// ResolveDIDKey extracts a public key from a did:key string
|
// ResolveDIDKey extracts a public key from a did:key string
|
||||||
func (customDIDPubKeyResolver) ResolveDIDKey(ctx context.Context, didStr string) (didkey.ID, error) {
|
func (customDIDPubKeyResolver) ResolveDIDKey(ctx context.Context, didStr string) (keys.DID, error) {
|
||||||
return didkey.Parse(didStr)
|
return keys.Parse(didStr)
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/types/bech32"
|
"github.com/cosmos/cosmos-sdk/types/bech32"
|
||||||
"github.com/golang-jwt/jwt"
|
"github.com/golang-jwt/jwt"
|
||||||
"github.com/onsonr/sonr/crypto/mpc"
|
"github.com/onsonr/sonr/crypto/keys"
|
||||||
"github.com/onsonr/sonr/crypto/ucan"
|
"github.com/onsonr/sonr/crypto/ucan"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -30,9 +30,6 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ucanKeyshare struct {
|
type ucanKeyshare struct {
|
||||||
userShare *mpc.UserKeyshare
|
|
||||||
valShare *mpc.ValKeyshare
|
|
||||||
|
|
||||||
addr string
|
addr string
|
||||||
issuerDID string
|
issuerDID string
|
||||||
}
|
}
|
||||||
@@ -97,18 +94,10 @@ func (k ucanKeyshare) newToken(audienceDID string, prf []Proof, att Attenuations
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ComputeIssuerDID(pk []byte) (string, string, error) {
|
func getIssuerDID(pk keys.PubKey) (string, string, error) {
|
||||||
addr, err := ComputeSonrAddr(pk)
|
addr, err := bech32.ConvertAndEncode("idx", pk.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("did:sonr:%s", addr), addr, nil
|
return fmt.Sprintf("did:sonr:%s", addr), addr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ComputeSonrAddr(pk []byte) (string, error) {
|
|
||||||
sonrAddr, err := bech32.ConvertAndEncode("idx", pk)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return sonrAddr, nil
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
package mpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/types/bech32"
|
||||||
|
"github.com/onsonr/sonr/crypto/core/curves"
|
||||||
|
"github.com/onsonr/sonr/crypto/core/protocol"
|
||||||
|
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1"
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func checkIteratedErrors(aErr, bErr error) error {
|
||||||
|
if aErr == protocol.ErrProtocolFinished && bErr == protocol.ErrProtocolFinished {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if aErr != protocol.ErrProtocolFinished {
|
||||||
|
return aErr
|
||||||
|
}
|
||||||
|
if bErr != protocol.ErrProtocolFinished {
|
||||||
|
return bErr
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func computeSonrAddr(pp Point) (string, error) {
|
||||||
|
pk := pp.ToAffineCompressed()
|
||||||
|
sonrAddr, err := bech32.ConvertAndEncode("idx", pk)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return sonrAddr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func hashKey(key []byte) []byte {
|
||||||
|
hash := sha3.New256()
|
||||||
|
hash.Write(key)
|
||||||
|
return hash.Sum(nil)[:32] // Use first 32 bytes of hash
|
||||||
|
}
|
||||||
|
|
||||||
|
func decryptKeyshare(msg []byte, key []byte, nonce []byte) ([]byte, error) {
|
||||||
|
hashedKey := hashKey(key)
|
||||||
|
block, err := aes.NewCipher(hashedKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
aesgcm, err := cipher.NewGCM(block)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
plaintext, err := aesgcm.Open(nil, nonce, msg, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return plaintext, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encryptKeyshare(msg Message, key []byte, nonce []byte) ([]byte, error) {
|
||||||
|
hashedKey := hashKey(key)
|
||||||
|
msgBytes, err := protocol.EncodeMessage(msg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
block, err := aes.NewCipher(hashedKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
aesgcm, err := cipher.NewGCM(block)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ciphertext := aesgcm.Seal(nil, nonce, []byte(msgBytes), nil)
|
||||||
|
return ciphertext, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAliceOut(msg *protocol.Message) (AliceOut, error) {
|
||||||
|
return dklsv1.DecodeAliceDkgResult(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAlicePubPoint(msg *protocol.Message) (Point, error) {
|
||||||
|
out, err := dklsv1.DecodeAliceDkgResult(msg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out.PublicKey, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBobOut(msg *protocol.Message) (BobOut, error) {
|
||||||
|
return dklsv1.DecodeBobDkgResult(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBobPubPoint(msg *protocol.Message) (Point, error) {
|
||||||
|
out, err := dklsv1.DecodeBobDkgResult(msg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out.PublicKey, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getEcdsaPoint builds an elliptic curve point from a compressed byte slice
|
||||||
|
func getEcdsaPoint(pubKey []byte) (*curves.EcPoint, error) {
|
||||||
|
crv := curves.K256()
|
||||||
|
x := new(big.Int).SetBytes(pubKey[1:33])
|
||||||
|
y := new(big.Int).SetBytes(pubKey[33:])
|
||||||
|
ecCurve, err := crv.ToEllipticCurve()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error converting curve: %v", err)
|
||||||
|
}
|
||||||
|
return &curves.EcPoint{X: x, Y: y, Curve: ecCurve}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func serializeSignature(sig *curves.EcdsaSignature) ([]byte, error) {
|
||||||
|
if sig == nil {
|
||||||
|
return nil, errors.New("nil signature")
|
||||||
|
}
|
||||||
|
|
||||||
|
rBytes := sig.R.Bytes()
|
||||||
|
sBytes := sig.S.Bytes()
|
||||||
|
|
||||||
|
// Ensure both components are 32 bytes
|
||||||
|
rPadded := make([]byte, 32)
|
||||||
|
sPadded := make([]byte, 32)
|
||||||
|
copy(rPadded[32-len(rBytes):], rBytes)
|
||||||
|
copy(sPadded[32-len(sBytes):], sBytes)
|
||||||
|
|
||||||
|
// Concatenate R and S
|
||||||
|
result := make([]byte, 64)
|
||||||
|
copy(result[0:32], rPadded)
|
||||||
|
copy(result[32:64], sPadded)
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func deserializeSignature(sigBytes []byte) (*curves.EcdsaSignature, error) {
|
||||||
|
if len(sigBytes) != 64 {
|
||||||
|
return nil, fmt.Errorf("invalid signature length: expected 64 bytes, got %d", len(sigBytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
r := new(big.Int).SetBytes(sigBytes[:32])
|
||||||
|
s := new(big.Int).SetBytes(sigBytes[32:])
|
||||||
|
|
||||||
|
return &curves.EcdsaSignature{
|
||||||
|
R: r,
|
||||||
|
S: s,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func userSignFunc(k *keyEnclave, bz []byte) (SignFunc, error) {
|
||||||
|
curve := curves.K256()
|
||||||
|
return dklsv1.NewBobSign(curve, sha3.New256(), bz, k.UserShare, protocol.Version1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func userRefreshFunc(k *keyEnclave) (RefreshFunc, error) {
|
||||||
|
curve := curves.K256()
|
||||||
|
return dklsv1.NewBobRefresh(curve, k.UserShare, protocol.Version1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func valSignFunc(k *keyEnclave, bz []byte) (SignFunc, error) {
|
||||||
|
curve := curves.K256()
|
||||||
|
return dklsv1.NewAliceSign(curve, sha3.New256(), bz, k.ValShare, protocol.Version1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func valRefreshFunc(k *keyEnclave) (RefreshFunc, error) {
|
||||||
|
curve := curves.K256()
|
||||||
|
return dklsv1.NewAliceRefresh(curve, k.ValShare, protocol.Version1)
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@ import (
|
|||||||
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1/dkg"
|
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1/dkg"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GenerationAndDeal produces private key material for alice and bob which they can later use in signing.
|
// GenerateAndDeal produces private key material for alice and bob which they can later use in signing.
|
||||||
// Running actual DKG is ALWAYS recommended over using this function, as this function breaks the security guarantees of DKG.
|
// Running actual DKG is ALWAYS recommended over using this function, as this function breaks the security guarantees of DKG.
|
||||||
// only use this function if you have a very good reason to.
|
// only use this function if you have a very good reason to.
|
||||||
func GenerateAndDeal(curve *curves.Curve) (*dkg.AliceOutput, *dkg.BobOutput, error) {
|
func GenerateAndDeal(curve *curves.Curve) (*dkg.AliceOutput, *dkg.BobOutput, error) {
|
||||||
|
|||||||
@@ -73,32 +73,6 @@ type Resource interface {
|
|||||||
Contains(b Resource) bool
|
Contains(b Resource) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type stringLengthRsc struct {
|
|
||||||
t string
|
|
||||||
v string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewStringLengthResource is a silly implementation of resource to use while
|
|
||||||
// I figure out what an OR filter on strings is. Don't use this.
|
|
||||||
func NewStringLengthResource(typ, val string) Resource {
|
|
||||||
return stringLengthRsc{
|
|
||||||
t: typ,
|
|
||||||
v: val,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r stringLengthRsc) Type() string {
|
|
||||||
return r.t
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r stringLengthRsc) Value() string {
|
|
||||||
return r.v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r stringLengthRsc) Contains(b Resource) bool {
|
|
||||||
return r.Type() == b.Type() && len(r.Value()) <= len(b.Value())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Capability is an action users can perform
|
// Capability is an action users can perform
|
||||||
type Capability interface {
|
type Capability interface {
|
||||||
// A Capability must be expressable as a string
|
// A Capability must be expressable as a string
|
||||||
|
|||||||
@@ -1,96 +0,0 @@
|
|||||||
package ucan
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAttenuationsContains(t *testing.T) {
|
|
||||||
aContains := [][2]string{
|
|
||||||
{
|
|
||||||
`[
|
|
||||||
{ "cap": "SUPER_USER", "dataset": "b5/world_bank_population"},
|
|
||||||
{ "cap": "OVERWRITE", "api": "https://api.qri.cloud" }
|
|
||||||
]`,
|
|
||||||
`[
|
|
||||||
{"cap": "SOFT_DELETE", "dataset": "b5/world_bank_population" }
|
|
||||||
]`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
`[
|
|
||||||
{ "cap": "SUPER_USER", "dataset": "b5/world_bank_population"},
|
|
||||||
{ "cap": "OVERWRITE", "api": "https://api.qri.cloud" }
|
|
||||||
]`,
|
|
||||||
`[
|
|
||||||
{"cap": "SUPER_USER", "dataset": "b5/world_bank_population" }
|
|
||||||
]`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, c := range aContains {
|
|
||||||
t.Run(fmt.Sprintf("contains_%d", i), func(t *testing.T) {
|
|
||||||
a := testAttenuations(c[0])
|
|
||||||
b := testAttenuations(c[1])
|
|
||||||
if !a.Contains(b) {
|
|
||||||
t.Errorf("expected a attenuations to contain b attenuations")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
aNotContains := [][2]string{
|
|
||||||
{
|
|
||||||
`[
|
|
||||||
{ "cap": "SUPER_USER", "dataset": "b5/world_bank_population"},
|
|
||||||
{ "cap": "OVERWRITE", "api": "https://api.qri.cloud" }
|
|
||||||
]`,
|
|
||||||
`[
|
|
||||||
{ "cap": "CREATE", "dataset": "b5" }
|
|
||||||
]`,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, c := range aNotContains {
|
|
||||||
t.Run(fmt.Sprintf("not_contains_%d", i), func(t *testing.T) {
|
|
||||||
a := testAttenuations(c[0])
|
|
||||||
b := testAttenuations(c[1])
|
|
||||||
if a.Contains(b) {
|
|
||||||
t.Errorf("expected a attenuations to NOT contain b attenuations")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func mustJSON(data string, v interface{}) {
|
|
||||||
if err := json.Unmarshal([]byte(data), v); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAttenuations(data string) Attenuations {
|
|
||||||
caps := NewNestedCapabilities("SUPER_USER", "OVERWRITE", "SOFT_DELETE", "REVISE", "CREATE")
|
|
||||||
|
|
||||||
v := []map[string]string{}
|
|
||||||
mustJSON(data, &v)
|
|
||||||
|
|
||||||
var att Attenuations
|
|
||||||
for _, x := range v {
|
|
||||||
var cap Capability
|
|
||||||
var rsc Resource
|
|
||||||
for key, val := range x {
|
|
||||||
switch key {
|
|
||||||
case CapKey:
|
|
||||||
cap = caps.Cap(val)
|
|
||||||
default:
|
|
||||||
rsc = NewStringLengthResource(key, val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
att = append(att, Attenuation{cap, rsc})
|
|
||||||
}
|
|
||||||
|
|
||||||
return att
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNestedCapabilities(t *testing.T) {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Code generated from Pkl module `sonr.motr.ATN`. DO NOT EDIT.
|
// Code generated from Pkl module `sonr.orm.UCAN`. DO NOT EDIT.
|
||||||
package attns
|
package attns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -7,11 +7,11 @@ import (
|
|||||||
"github.com/apple/pkl-go/pkl"
|
"github.com/apple/pkl-go/pkl"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ATN struct {
|
type UCAN struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadFromPath loads the pkl module at the given path and evaluates it into a ATN
|
// LoadFromPath loads the pkl module at the given path and evaluates it into a UCAN
|
||||||
func LoadFromPath(ctx context.Context, path string) (ret *ATN, err error) {
|
func LoadFromPath(ctx context.Context, path string) (ret *UCAN, err error) {
|
||||||
evaluator, err := pkl.NewEvaluator(ctx, pkl.PreconfiguredOptions)
|
evaluator, err := pkl.NewEvaluator(ctx, pkl.PreconfiguredOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -26,9 +26,9 @@ func LoadFromPath(ctx context.Context, path string) (ret *ATN, err error) {
|
|||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load loads the pkl module at the given source and evaluates it with the given evaluator into a ATN
|
// Load loads the pkl module at the given source and evaluates it with the given evaluator into a UCAN
|
||||||
func Load(ctx context.Context, evaluator pkl.Evaluator, source *pkl.ModuleSource) (*ATN, error) {
|
func Load(ctx context.Context, evaluator pkl.Evaluator, source *pkl.ModuleSource) (*UCAN, error) {
|
||||||
var ret ATN
|
var ret UCAN
|
||||||
if err := evaluator.EvaluateModule(ctx, source, &ret); err != nil {
|
if err := evaluator.EvaluateModule(ctx, source, &ret); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
// Code generated from Pkl module `sonr.motr.ATN`. DO NOT EDIT.
|
|
||||||
package capability
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Capability string
|
|
||||||
|
|
||||||
const (
|
|
||||||
CAPOWNER Capability = "CAP_OWNER"
|
|
||||||
CAPOPERATOR Capability = "CAP_OPERATOR"
|
|
||||||
CAPOBSERVER Capability = "CAP_OBSERVER"
|
|
||||||
CAPAUTHENTICATE Capability = "CAP_AUTHENTICATE"
|
|
||||||
CAPAUTHORIZE Capability = "CAP_AUTHORIZE"
|
|
||||||
CAPDELEGATE Capability = "CAP_DELEGATE"
|
|
||||||
CAPINVOKE Capability = "CAP_INVOKE"
|
|
||||||
CAPEXECUTE Capability = "CAP_EXECUTE"
|
|
||||||
CAPPROPOSE Capability = "CAP_PROPOSE"
|
|
||||||
CAPSIGN Capability = "CAP_SIGN"
|
|
||||||
CAPSETPOLICY Capability = "CAP_SET_POLICY"
|
|
||||||
CAPSETTHRESHOLD Capability = "CAP_SET_THRESHOLD"
|
|
||||||
CAPRECOVER Capability = "CAP_RECOVER"
|
|
||||||
CAPSOCIAL Capability = "CAP_SOCIAL"
|
|
||||||
CAPVOTE Capability = "CAP_VOTE"
|
|
||||||
CAPRESOLVER Capability = "CAP_RESOLVER"
|
|
||||||
CAPPRODUCER Capability = "CAP_PRODUCER"
|
|
||||||
)
|
|
||||||
|
|
||||||
// String returns the string representation of Capability
|
|
||||||
func (rcv Capability) String() string {
|
|
||||||
return string(rcv)
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ encoding.BinaryUnmarshaler = new(Capability)
|
|
||||||
|
|
||||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler for Capability.
|
|
||||||
func (rcv *Capability) UnmarshalBinary(data []byte) error {
|
|
||||||
switch str := string(data); str {
|
|
||||||
case "CAP_OWNER":
|
|
||||||
*rcv = CAPOWNER
|
|
||||||
case "CAP_OPERATOR":
|
|
||||||
*rcv = CAPOPERATOR
|
|
||||||
case "CAP_OBSERVER":
|
|
||||||
*rcv = CAPOBSERVER
|
|
||||||
case "CAP_AUTHENTICATE":
|
|
||||||
*rcv = CAPAUTHENTICATE
|
|
||||||
case "CAP_AUTHORIZE":
|
|
||||||
*rcv = CAPAUTHORIZE
|
|
||||||
case "CAP_DELEGATE":
|
|
||||||
*rcv = CAPDELEGATE
|
|
||||||
case "CAP_INVOKE":
|
|
||||||
*rcv = CAPINVOKE
|
|
||||||
case "CAP_EXECUTE":
|
|
||||||
*rcv = CAPEXECUTE
|
|
||||||
case "CAP_PROPOSE":
|
|
||||||
*rcv = CAPPROPOSE
|
|
||||||
case "CAP_SIGN":
|
|
||||||
*rcv = CAPSIGN
|
|
||||||
case "CAP_SET_POLICY":
|
|
||||||
*rcv = CAPSETPOLICY
|
|
||||||
case "CAP_SET_THRESHOLD":
|
|
||||||
*rcv = CAPSETTHRESHOLD
|
|
||||||
case "CAP_RECOVER":
|
|
||||||
*rcv = CAPRECOVER
|
|
||||||
case "CAP_SOCIAL":
|
|
||||||
*rcv = CAPSOCIAL
|
|
||||||
case "CAP_VOTE":
|
|
||||||
*rcv = CAPVOTE
|
|
||||||
case "CAP_RESOLVER":
|
|
||||||
*rcv = CAPRESOLVER
|
|
||||||
case "CAP_PRODUCER":
|
|
||||||
*rcv = CAPPRODUCER
|
|
||||||
default:
|
|
||||||
return fmt.Errorf(`illegal: "%s" is not a valid Capability`, str)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
package capability
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
// Code generated from Pkl module `sonr.orm.UCAN`. DO NOT EDIT.
|
||||||
|
package capaccount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CapAccount string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ExecBroadcast CapAccount = "exec/broadcast"
|
||||||
|
ExecQuery CapAccount = "exec/query"
|
||||||
|
ExecSimulate CapAccount = "exec/simulate"
|
||||||
|
ExecVote CapAccount = "exec/vote"
|
||||||
|
ExecDelegate CapAccount = "exec/delegate"
|
||||||
|
ExecInvoke CapAccount = "exec/invoke"
|
||||||
|
ExecSend CapAccount = "exec/send"
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns the string representation of CapAccount
|
||||||
|
func (rcv CapAccount) String() string {
|
||||||
|
return string(rcv)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ encoding.BinaryUnmarshaler = new(CapAccount)
|
||||||
|
|
||||||
|
// UnmarshalBinary implements encoding.BinaryUnmarshaler for CapAccount.
|
||||||
|
func (rcv *CapAccount) UnmarshalBinary(data []byte) error {
|
||||||
|
switch str := string(data); str {
|
||||||
|
case "exec/broadcast":
|
||||||
|
*rcv = ExecBroadcast
|
||||||
|
case "exec/query":
|
||||||
|
*rcv = ExecQuery
|
||||||
|
case "exec/simulate":
|
||||||
|
*rcv = ExecSimulate
|
||||||
|
case "exec/vote":
|
||||||
|
*rcv = ExecVote
|
||||||
|
case "exec/delegate":
|
||||||
|
*rcv = ExecDelegate
|
||||||
|
case "exec/invoke":
|
||||||
|
*rcv = ExecInvoke
|
||||||
|
case "exec/send":
|
||||||
|
*rcv = ExecSend
|
||||||
|
default:
|
||||||
|
return fmt.Errorf(`illegal: "%s" is not a valid CapAccount`, str)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package capaccount
|
||||||
|
|
||||||
|
import "github.com/onsonr/sonr/crypto/ucan"
|
||||||
|
|
||||||
|
func NewCap(ty CapAccount) ucan.Capability {
|
||||||
|
return ucan.Capability(ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CapAccount) Contains(b ucan.Capability) bool {
|
||||||
|
return c.String() == b.String()
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
// Code generated from Pkl module `sonr.orm.UCAN`. DO NOT EDIT.
|
||||||
|
package capinterchain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CapInterchain string
|
||||||
|
|
||||||
|
const (
|
||||||
|
TransferSwap CapInterchain = "transfer/swap"
|
||||||
|
TransferSend CapInterchain = "transfer/send"
|
||||||
|
TransferAtomic CapInterchain = "transfer/atomic"
|
||||||
|
TransferBatch CapInterchain = "transfer/batch"
|
||||||
|
TransferP2p CapInterchain = "transfer/p2p"
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns the string representation of CapInterchain
|
||||||
|
func (rcv CapInterchain) String() string {
|
||||||
|
return string(rcv)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ encoding.BinaryUnmarshaler = new(CapInterchain)
|
||||||
|
|
||||||
|
// UnmarshalBinary implements encoding.BinaryUnmarshaler for CapInterchain.
|
||||||
|
func (rcv *CapInterchain) UnmarshalBinary(data []byte) error {
|
||||||
|
switch str := string(data); str {
|
||||||
|
case "transfer/swap":
|
||||||
|
*rcv = TransferSwap
|
||||||
|
case "transfer/send":
|
||||||
|
*rcv = TransferSend
|
||||||
|
case "transfer/atomic":
|
||||||
|
*rcv = TransferAtomic
|
||||||
|
case "transfer/batch":
|
||||||
|
*rcv = TransferBatch
|
||||||
|
case "transfer/p2p":
|
||||||
|
*rcv = TransferP2p
|
||||||
|
default:
|
||||||
|
return fmt.Errorf(`illegal: "%s" is not a valid CapInterchain`, str)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package capinterchain
|
||||||
|
|
||||||
|
import "github.com/onsonr/sonr/crypto/ucan"
|
||||||
|
|
||||||
|
func NewCap(ty CapInterchain) ucan.Capability {
|
||||||
|
return ucan.Capability(ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CapInterchain) Contains(b ucan.Capability) bool {
|
||||||
|
return c.String() == b.String()
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
// Code generated from Pkl module `sonr.orm.UCAN`. DO NOT EDIT.
|
||||||
|
package capvault
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CapVault string
|
||||||
|
|
||||||
|
const (
|
||||||
|
CrudAsset CapVault = "crud/asset"
|
||||||
|
CrudAuthzgrant CapVault = "crud/authzgrant"
|
||||||
|
CrudProfile CapVault = "crud/profile"
|
||||||
|
CrudRecord CapVault = "crud/record"
|
||||||
|
UseRecovery CapVault = "use/recovery"
|
||||||
|
UseSync CapVault = "use/sync"
|
||||||
|
UseSigner CapVault = "use/signer"
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns the string representation of CapVault
|
||||||
|
func (rcv CapVault) String() string {
|
||||||
|
return string(rcv)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ encoding.BinaryUnmarshaler = new(CapVault)
|
||||||
|
|
||||||
|
// UnmarshalBinary implements encoding.BinaryUnmarshaler for CapVault.
|
||||||
|
func (rcv *CapVault) UnmarshalBinary(data []byte) error {
|
||||||
|
switch str := string(data); str {
|
||||||
|
case "crud/asset":
|
||||||
|
*rcv = CrudAsset
|
||||||
|
case "crud/authzgrant":
|
||||||
|
*rcv = CrudAuthzgrant
|
||||||
|
case "crud/profile":
|
||||||
|
*rcv = CrudProfile
|
||||||
|
case "crud/record":
|
||||||
|
*rcv = CrudRecord
|
||||||
|
case "use/recovery":
|
||||||
|
*rcv = UseRecovery
|
||||||
|
case "use/sync":
|
||||||
|
*rcv = UseSync
|
||||||
|
case "use/signer":
|
||||||
|
*rcv = UseSigner
|
||||||
|
default:
|
||||||
|
return fmt.Errorf(`illegal: "%s" is not a valid CapVault`, str)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package capvault
|
||||||
|
|
||||||
|
import "github.com/onsonr/sonr/crypto/ucan"
|
||||||
|
|
||||||
|
func NewCap(ty CapVault) ucan.Capability {
|
||||||
|
return ucan.Capability(ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c CapVault) Contains(b ucan.Capability) bool {
|
||||||
|
return c.String() == b.String()
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
// Package attns implements the UCAN resource and capability types
|
||||||
|
package attns
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/onsonr/sonr/crypto/ucan"
|
||||||
|
"github.com/onsonr/sonr/crypto/ucan/attns/capaccount"
|
||||||
|
"github.com/onsonr/sonr/crypto/ucan/attns/capinterchain"
|
||||||
|
"github.com/onsonr/sonr/crypto/ucan/attns/capvault"
|
||||||
|
"github.com/onsonr/sonr/crypto/ucan/attns/resaccount"
|
||||||
|
"github.com/onsonr/sonr/crypto/ucan/attns/resinterchain"
|
||||||
|
"github.com/onsonr/sonr/crypto/ucan/attns/resvault"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Capability hierarchy for sonr network
|
||||||
|
// -------------------------------------
|
||||||
|
// VAULT (DWN)
|
||||||
|
//
|
||||||
|
// └─ CRUD/ASSET
|
||||||
|
// └─ CRUD/AUTHZGRANT
|
||||||
|
// └─ CRUD/PROFILE
|
||||||
|
// └─ CRUD/RECORD
|
||||||
|
// └─ USE/RECOVERY
|
||||||
|
// └─ USE/SYNC
|
||||||
|
// └─ USE/SIGNER
|
||||||
|
//
|
||||||
|
// ACCOUNT (DID)
|
||||||
|
//
|
||||||
|
// └─ EXEC/BROADCAST
|
||||||
|
// └─ EXEC/QUERY
|
||||||
|
// └─ EXEC/SIMULATE
|
||||||
|
// └─ EXEC/VOTE
|
||||||
|
// └─ EXEC/DELEGATE
|
||||||
|
// └─ EXEC/INVOKE
|
||||||
|
// └─ EXEC/SEND
|
||||||
|
//
|
||||||
|
// INTERCHAIN
|
||||||
|
//
|
||||||
|
// └─ TRANSFER/SWAP
|
||||||
|
// └─ TRANSFER/SEND
|
||||||
|
// └─ TRANSFER/ATOMIC
|
||||||
|
// └─ TRANSFER/BATCH
|
||||||
|
// └─ TRANSFER/P2P
|
||||||
|
// └─ TRANSFER/SEND
|
||||||
|
|
||||||
|
type Capability string
|
||||||
|
|
||||||
|
const (
|
||||||
|
CapExecBroadcast = capaccount.ExecBroadcast
|
||||||
|
CapExecQuery = capaccount.ExecQuery
|
||||||
|
CapExecSimulate = capaccount.ExecSimulate
|
||||||
|
CapExecVote = capaccount.ExecVote
|
||||||
|
CapExecDelegate = capaccount.ExecDelegate
|
||||||
|
CapExecInvoke = capaccount.ExecInvoke
|
||||||
|
CapExecSend = capaccount.ExecSend
|
||||||
|
|
||||||
|
CapTransferSwap = capinterchain.TransferSwap
|
||||||
|
CapTransferSend = capinterchain.TransferSend
|
||||||
|
CapTransferAtomic = capinterchain.TransferAtomic
|
||||||
|
CapTransferBatch = capinterchain.TransferBatch
|
||||||
|
CapTransferP2P = capinterchain.TransferP2p
|
||||||
|
|
||||||
|
CapCrudAsset = capvault.CrudAsset
|
||||||
|
CapCrudAuthzgrant = capvault.CrudAuthzgrant
|
||||||
|
CapCrudProfile = capvault.CrudProfile
|
||||||
|
CapCrudRecord = capvault.CrudRecord
|
||||||
|
CapUseRecovery = capvault.UseRecovery
|
||||||
|
CapUseSync = capvault.UseSync
|
||||||
|
CapUseSigner = capvault.UseSigner
|
||||||
|
)
|
||||||
|
|
||||||
|
type NewCapFunc func(string) ucan.Capability
|
||||||
|
|
||||||
|
type BuildResourceFunc func(string, string) ucan.Resource
|
||||||
|
|
||||||
|
func CreateArray(attns ...ucan.Attenuation) ucan.Attenuations {
|
||||||
|
return ucan.Attenuations(attns)
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(cap ucan.Capability, rsc ucan.Resource) ucan.Attenuation {
|
||||||
|
return ucan.Attenuation{
|
||||||
|
Cap: cap,
|
||||||
|
Rsc: rsc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAccountCap creates a new account capability
|
||||||
|
func NewAccountCap(ty capaccount.CapAccount) ucan.Capability {
|
||||||
|
return capaccount.NewCap(ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInterchainCap creates a new interchain capability
|
||||||
|
func NewInterchainCap(ty capinterchain.CapInterchain) ucan.Capability {
|
||||||
|
return capinterchain.NewCap(ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewVaultCap creates a new vault capability
|
||||||
|
func NewVaultCap(ty capvault.CapVault) ucan.Capability {
|
||||||
|
return capvault.NewCap(ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildAccountResource creates a new account resource
|
||||||
|
func BuildAccountResource(ty resaccount.ResAccount, value string) ucan.Resource {
|
||||||
|
return resaccount.Build(ty, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildInterchainResource creates a new interchain resource
|
||||||
|
func BuildInterchainResource(ty resinterchain.ResInterchain, value string) ucan.Resource {
|
||||||
|
return resinterchain.Build(ty, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildVaultResource creates a new vault resource
|
||||||
|
func BuildVaultResource(ty resvault.ResVault, value string) ucan.Resource {
|
||||||
|
return resvault.Build(ty, value)
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
// Code generated from Pkl module `sonr.motr.ATN`. DO NOT EDIT.
|
// Code generated from Pkl module `sonr.orm.UCAN`. DO NOT EDIT.
|
||||||
package attns
|
package attns
|
||||||
|
|
||||||
import "github.com/apple/pkl-go/pkl"
|
import "github.com/apple/pkl-go/pkl"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
pkl.RegisterMapping("sonr.motr.ATN", ATN{})
|
pkl.RegisterMapping("sonr.orm.UCAN", UCAN{})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
// Code generated from Pkl module `sonr.motr.ATN`. DO NOT EDIT.
|
|
||||||
package policytype
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PolicyType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
POLICYTHRESHOLD PolicyType = "POLICY_THRESHOLD"
|
|
||||||
POLICYTIMELOCK PolicyType = "POLICY_TIMELOCK"
|
|
||||||
POLICYWHITELIST PolicyType = "POLICY_WHITELIST"
|
|
||||||
POLICYKEYGEN PolicyType = "POLICY_KEYGEN"
|
|
||||||
)
|
|
||||||
|
|
||||||
// String returns the string representation of PolicyType
|
|
||||||
func (rcv PolicyType) String() string {
|
|
||||||
return string(rcv)
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ encoding.BinaryUnmarshaler = new(PolicyType)
|
|
||||||
|
|
||||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler for PolicyType.
|
|
||||||
func (rcv *PolicyType) UnmarshalBinary(data []byte) error {
|
|
||||||
switch str := string(data); str {
|
|
||||||
case "POLICY_THRESHOLD":
|
|
||||||
*rcv = POLICYTHRESHOLD
|
|
||||||
case "POLICY_TIMELOCK":
|
|
||||||
*rcv = POLICYTIMELOCK
|
|
||||||
case "POLICY_WHITELIST":
|
|
||||||
*rcv = POLICYWHITELIST
|
|
||||||
case "POLICY_KEYGEN":
|
|
||||||
*rcv = POLICYKEYGEN
|
|
||||||
default:
|
|
||||||
return fmt.Errorf(`illegal: "%s" is not a valid PolicyType`, str)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
// Code generated from Pkl module `sonr.orm.UCAN`. DO NOT EDIT.
|
||||||
|
package resaccount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ResAccount string
|
||||||
|
|
||||||
|
const (
|
||||||
|
AccSequence ResAccount = "acc/sequence"
|
||||||
|
AccNumber ResAccount = "acc/number"
|
||||||
|
ChainId ResAccount = "chain/id"
|
||||||
|
AssetCode ResAccount = "asset/code"
|
||||||
|
AuthzGrant ResAccount = "authz/grant"
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns the string representation of ResAccount
|
||||||
|
func (rcv ResAccount) String() string {
|
||||||
|
return string(rcv)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ encoding.BinaryUnmarshaler = new(ResAccount)
|
||||||
|
|
||||||
|
// UnmarshalBinary implements encoding.BinaryUnmarshaler for ResAccount.
|
||||||
|
func (rcv *ResAccount) UnmarshalBinary(data []byte) error {
|
||||||
|
switch str := string(data); str {
|
||||||
|
case "acc/sequence":
|
||||||
|
*rcv = AccSequence
|
||||||
|
case "acc/number":
|
||||||
|
*rcv = AccNumber
|
||||||
|
case "chain/id":
|
||||||
|
*rcv = ChainId
|
||||||
|
case "asset/code":
|
||||||
|
*rcv = AssetCode
|
||||||
|
case "authz/grant":
|
||||||
|
*rcv = AuthzGrant
|
||||||
|
default:
|
||||||
|
return fmt.Errorf(`illegal: "%s" is not a valid ResAccount`, str)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package resaccount
|
||||||
|
|
||||||
|
import "github.com/onsonr/sonr/crypto/ucan"
|
||||||
|
|
||||||
|
func Build(ty ResAccount, value string) ucan.Resource {
|
||||||
|
return newStringLengthResource(ty.String(), value)
|
||||||
|
}
|
||||||
|
|
||||||
|
type stringLengthRsc struct {
|
||||||
|
t string
|
||||||
|
v string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStringLengthResource is a silly implementation of resource to use while
|
||||||
|
// I figure out what an OR filter on strings is. Don't use this.
|
||||||
|
func newStringLengthResource(typ, val string) ucan.Resource {
|
||||||
|
return stringLengthRsc{
|
||||||
|
t: typ,
|
||||||
|
v: val,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r stringLengthRsc) Type() string {
|
||||||
|
return r.t
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r stringLengthRsc) Value() string {
|
||||||
|
return r.v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r stringLengthRsc) Contains(b ucan.Resource) bool {
|
||||||
|
return r.Type() == b.Type() && len(r.Value()) <= len(b.Value())
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
// Code generated from Pkl module `sonr.orm.UCAN`. DO NOT EDIT.
|
||||||
|
package resinterchain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ResInterchain string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ChannnelPort ResInterchain = "channnel/port"
|
||||||
|
ChainId ResInterchain = "chain/id"
|
||||||
|
ChainName ResInterchain = "chain/name"
|
||||||
|
AccHost ResInterchain = "acc/host"
|
||||||
|
AccController ResInterchain = "acc/controller"
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns the string representation of ResInterchain
|
||||||
|
func (rcv ResInterchain) String() string {
|
||||||
|
return string(rcv)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ encoding.BinaryUnmarshaler = new(ResInterchain)
|
||||||
|
|
||||||
|
// UnmarshalBinary implements encoding.BinaryUnmarshaler for ResInterchain.
|
||||||
|
func (rcv *ResInterchain) UnmarshalBinary(data []byte) error {
|
||||||
|
switch str := string(data); str {
|
||||||
|
case "channnel/port":
|
||||||
|
*rcv = ChannnelPort
|
||||||
|
case "chain/id":
|
||||||
|
*rcv = ChainId
|
||||||
|
case "chain/name":
|
||||||
|
*rcv = ChainName
|
||||||
|
case "acc/host":
|
||||||
|
*rcv = AccHost
|
||||||
|
case "acc/controller":
|
||||||
|
*rcv = AccController
|
||||||
|
default:
|
||||||
|
return fmt.Errorf(`illegal: "%s" is not a valid ResInterchain`, str)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package resinterchain
|
||||||
|
|
||||||
|
import "github.com/onsonr/sonr/crypto/ucan"
|
||||||
|
|
||||||
|
func Build(ty ResInterchain, value string) ucan.Resource {
|
||||||
|
return newStringLengthResource(ty.String(), value)
|
||||||
|
}
|
||||||
|
|
||||||
|
type stringLengthRsc struct {
|
||||||
|
t string
|
||||||
|
v string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStringLengthResource is a silly implementation of resource to use while
|
||||||
|
// I figure out what an OR filter on strings is. Don't use this.
|
||||||
|
func newStringLengthResource(typ, val string) ucan.Resource {
|
||||||
|
return stringLengthRsc{
|
||||||
|
t: typ,
|
||||||
|
v: val,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r stringLengthRsc) Type() string {
|
||||||
|
return r.t
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r stringLengthRsc) Value() string {
|
||||||
|
return r.v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r stringLengthRsc) Contains(b ucan.Resource) bool {
|
||||||
|
return r.Type() == b.Type() && len(r.Value()) <= len(b.Value())
|
||||||
|
}
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
// Code generated from Pkl module `sonr.motr.ATN`. DO NOT EDIT.
|
|
||||||
package resourcetype
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ResourceType string
|
|
||||||
|
|
||||||
const (
|
|
||||||
RESACCOUNT ResourceType = "RES_ACCOUNT"
|
|
||||||
RESTRANSACTION ResourceType = "RES_TRANSACTION"
|
|
||||||
RESPOLICY ResourceType = "RES_POLICY"
|
|
||||||
RESRECOVERY ResourceType = "RES_RECOVERY"
|
|
||||||
RESVAULT ResourceType = "RES_VAULT"
|
|
||||||
RESIPFS ResourceType = "RES_IPFS"
|
|
||||||
RESIPNS ResourceType = "RES_IPNS"
|
|
||||||
RESKEYSHARE ResourceType = "RES_KEYSHARE"
|
|
||||||
)
|
|
||||||
|
|
||||||
// String returns the string representation of ResourceType
|
|
||||||
func (rcv ResourceType) String() string {
|
|
||||||
return string(rcv)
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ encoding.BinaryUnmarshaler = new(ResourceType)
|
|
||||||
|
|
||||||
// UnmarshalBinary implements encoding.BinaryUnmarshaler for ResourceType.
|
|
||||||
func (rcv *ResourceType) UnmarshalBinary(data []byte) error {
|
|
||||||
switch str := string(data); str {
|
|
||||||
case "RES_ACCOUNT":
|
|
||||||
*rcv = RESACCOUNT
|
|
||||||
case "RES_TRANSACTION":
|
|
||||||
*rcv = RESTRANSACTION
|
|
||||||
case "RES_POLICY":
|
|
||||||
*rcv = RESPOLICY
|
|
||||||
case "RES_RECOVERY":
|
|
||||||
*rcv = RESRECOVERY
|
|
||||||
case "RES_VAULT":
|
|
||||||
*rcv = RESVAULT
|
|
||||||
case "RES_IPFS":
|
|
||||||
*rcv = RESIPFS
|
|
||||||
case "RES_IPNS":
|
|
||||||
*rcv = RESIPNS
|
|
||||||
case "RES_KEYSHARE":
|
|
||||||
*rcv = RESKEYSHARE
|
|
||||||
default:
|
|
||||||
return fmt.Errorf(`illegal: "%s" is not a valid ResourceType`, str)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package resourcetype
|
|
||||||
|
|
||||||
// Resource is a unique identifier for a thing, usually stored state. Resources
|
|
||||||
// are organized by string types
|
|
||||||
type Resource interface {
|
|
||||||
Type() ResourceType
|
|
||||||
Value() string
|
|
||||||
Contains(b Resource) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type stringResource struct {
|
|
||||||
t ResourceType
|
|
||||||
v string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r stringResource) Type() ResourceType {
|
|
||||||
return r.t
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r stringResource) Value() string {
|
|
||||||
return r.v
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r stringResource) Contains(b Resource) bool {
|
|
||||||
return r.Type() == b.Type() && len(r.Value()) <= len(b.Value())
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewResource(typ ResourceType, val string) Resource {
|
|
||||||
return stringResource{
|
|
||||||
t: typ,
|
|
||||||
v: val,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
// Code generated from Pkl module `sonr.orm.UCAN`. DO NOT EDIT.
|
||||||
|
package resvault
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ResVault string
|
||||||
|
|
||||||
|
const (
|
||||||
|
KsEnclave ResVault = "ks/enclave"
|
||||||
|
LocCid ResVault = "loc/cid"
|
||||||
|
LocEntity ResVault = "loc/entity"
|
||||||
|
LocIpns ResVault = "loc/ipns"
|
||||||
|
AddrSonr ResVault = "addr/sonr"
|
||||||
|
ChainCode ResVault = "chain/code"
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns the string representation of ResVault
|
||||||
|
func (rcv ResVault) String() string {
|
||||||
|
return string(rcv)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ encoding.BinaryUnmarshaler = new(ResVault)
|
||||||
|
|
||||||
|
// UnmarshalBinary implements encoding.BinaryUnmarshaler for ResVault.
|
||||||
|
func (rcv *ResVault) UnmarshalBinary(data []byte) error {
|
||||||
|
switch str := string(data); str {
|
||||||
|
case "ks/enclave":
|
||||||
|
*rcv = KsEnclave
|
||||||
|
case "loc/cid":
|
||||||
|
*rcv = LocCid
|
||||||
|
case "loc/entity":
|
||||||
|
*rcv = LocEntity
|
||||||
|
case "loc/ipns":
|
||||||
|
*rcv = LocIpns
|
||||||
|
case "addr/sonr":
|
||||||
|
*rcv = AddrSonr
|
||||||
|
case "chain/code":
|
||||||
|
*rcv = ChainCode
|
||||||
|
default:
|
||||||
|
return fmt.Errorf(`illegal: "%s" is not a valid ResVault`, str)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package resvault
|
||||||
|
|
||||||
|
import "github.com/onsonr/sonr/crypto/ucan"
|
||||||
|
|
||||||
|
func Build(ty ResVault, value string) ucan.Resource {
|
||||||
|
return newStringLengthResource(ty.String(), value)
|
||||||
|
}
|
||||||
|
|
||||||
|
type stringLengthRsc struct {
|
||||||
|
t string
|
||||||
|
v string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStringLengthResource is a silly implementation of resource to use while
|
||||||
|
// I figure out what an OR filter on strings is. Don't use this.
|
||||||
|
func newStringLengthResource(typ, val string) ucan.Resource {
|
||||||
|
return stringLengthRsc{
|
||||||
|
t: typ,
|
||||||
|
v: val,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r stringLengthRsc) Type() string {
|
||||||
|
return r.t
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r stringLengthRsc) Value() string {
|
||||||
|
return r.v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r stringLengthRsc) Contains(b ucan.Resource) bool {
|
||||||
|
return r.Type() == b.Type() && len(r.Value()) <= len(b.Value())
|
||||||
|
}
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
package ucan
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/onsonr/sonr/crypto/mpc"
|
|
||||||
"github.com/onsonr/sonr/crypto/ucan/attns/capability"
|
|
||||||
"github.com/onsonr/sonr/crypto/ucan/attns/policytype"
|
|
||||||
"github.com/onsonr/sonr/crypto/ucan/attns/resourcetype"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewSmartAccount creates default attenuations for a smart account
|
|
||||||
func NewSmartAccount(
|
|
||||||
accountAddr string,
|
|
||||||
) Attenuations {
|
|
||||||
caps := AccountPermissions.GetCapabilities()
|
|
||||||
return Attenuations{
|
|
||||||
// Owner capabilities
|
|
||||||
{Cap: caps.Cap(CapOwner.String()), Rsc: NewResource(ResAccount, accountAddr)},
|
|
||||||
|
|
||||||
// Operation capabilities
|
|
||||||
{Cap: caps.Cap(capability.CAPEXECUTE.String()), Rsc: NewResource(ResTransaction, fmt.Sprintf("%s:*", accountAddr))},
|
|
||||||
{Cap: caps.Cap(capability.CAPPROPOSE.String()), Rsc: NewResource(ResTransaction, fmt.Sprintf("%s:*", accountAddr))},
|
|
||||||
{Cap: caps.Cap(capability.CAPSIGN.String()), Rsc: NewResource(ResTransaction, fmt.Sprintf("%s:*", accountAddr))},
|
|
||||||
|
|
||||||
// Policy capabilities
|
|
||||||
{Cap: caps.Cap(capability.CAPSETPOLICY.String()), Rsc: NewResource(ResPolicy, fmt.Sprintf("%s:*", accountAddr))},
|
|
||||||
{Cap: caps.Cap(capability.CAPSETTHRESHOLD.String()), Rsc: NewResource(ResPolicy, fmt.Sprintf("%s:threshold", accountAddr))},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSmartAccountPolicy creates attenuations for policy management
|
|
||||||
func NewSmartAccountPolicy(
|
|
||||||
accountAddr string,
|
|
||||||
policyType policytype.PolicyType,
|
|
||||||
) Attenuations {
|
|
||||||
caps := AccountPermissions.GetCapabilities()
|
|
||||||
return Attenuations{
|
|
||||||
{
|
|
||||||
Cap: caps.Cap(capability.CAPSETPOLICY.String()),
|
|
||||||
Rsc: NewResource(
|
|
||||||
ResPolicy,
|
|
||||||
fmt.Sprintf("%s:%s", accountAddr, policyType),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SmartAccountCapabilities defines the capability hierarchy
|
|
||||||
func SmartAccountCapabilities() []string {
|
|
||||||
return []string{
|
|
||||||
CapOwner.String(),
|
|
||||||
CapOperator.String(),
|
|
||||||
CapObserver.String(),
|
|
||||||
CapExecute.String(),
|
|
||||||
CapPropose.String(),
|
|
||||||
CapSign.String(),
|
|
||||||
CapSetPolicy.String(),
|
|
||||||
CapSetThreshold.String(),
|
|
||||||
CapRecover.String(),
|
|
||||||
CapSocial.String(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateVaultAttenuations creates default attenuations for a smart account
|
|
||||||
func NewService(
|
|
||||||
origin string,
|
|
||||||
) Attenuations {
|
|
||||||
caps := ServicePermissions.GetCapabilities()
|
|
||||||
return Attenuations{
|
|
||||||
// Owner capabilities
|
|
||||||
{Cap: caps.Cap(capability.CAPOWNER.String()), Rsc: NewResource(resourcetype.RESACCOUNT, origin)},
|
|
||||||
|
|
||||||
// Operation capabilities
|
|
||||||
{Cap: caps.Cap(capability.CAPEXECUTE.String()), Rsc: NewResource(resourcetype.RESTRANSACTION, fmt.Sprintf("%s:*", origin))},
|
|
||||||
{Cap: caps.Cap(capability.CAPPROPOSE.String()), Rsc: NewResource(resourcetype.RESTRANSACTION, fmt.Sprintf("%s:*", origin))},
|
|
||||||
{Cap: caps.Cap(capability.CAPSIGN.String()), Rsc: NewResource(resourcetype.RESTRANSACTION, fmt.Sprintf("%s:*", origin))},
|
|
||||||
|
|
||||||
// Policy capabilities
|
|
||||||
{Cap: caps.Cap(capability.CAPSETPOLICY.String()), Rsc: NewResource(resourcetype.RESPOLICY, fmt.Sprintf("%s:*", origin))},
|
|
||||||
{Cap: caps.Cap(capability.CAPSETTHRESHOLD.String()), Rsc: NewResource(resourcetype.RESPOLICY, fmt.Sprintf("%s:threshold", origin))},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ServiceCapabilities defines the capability hierarchy
|
|
||||||
func ServiceCapabilities() []string {
|
|
||||||
return []string{
|
|
||||||
CapOwner.String(),
|
|
||||||
CapOperator.String(),
|
|
||||||
CapObserver.String(),
|
|
||||||
CapExecute.String(),
|
|
||||||
CapPropose.String(),
|
|
||||||
CapSign.String(),
|
|
||||||
CapResolver.String(),
|
|
||||||
CapProducer.String(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewVault creates default attenuations for a smart account
|
|
||||||
func NewVault(
|
|
||||||
kss mpc.Keyset,
|
|
||||||
) Attenuations {
|
|
||||||
accountAddr, err := mpc.ComputeSonrAddr(kss.User().GetPublicKey())
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
caps := VaultPermissions.GetCapabilities()
|
|
||||||
return Attenuations{
|
|
||||||
// Owner capabilities
|
|
||||||
{Cap: caps.Cap(capability.CAPOWNER.String()), Rsc: NewResource(resourcetype.RESACCOUNT, accountAddr)},
|
|
||||||
|
|
||||||
// Operation capabilities
|
|
||||||
{Cap: caps.Cap(capability.CAPEXECUTE.String()), Rsc: NewResource(resourcetype.RESTRANSACTION, fmt.Sprintf("%s:*", accountAddr))},
|
|
||||||
{Cap: caps.Cap(capability.CAPPROPOSE.String()), Rsc: NewResource(resourcetype.RESTRANSACTION, fmt.Sprintf("%s:*", accountAddr))},
|
|
||||||
{Cap: caps.Cap(capability.CAPSIGN.String()), Rsc: NewResource(resourcetype.RESTRANSACTION, fmt.Sprintf("%s:*", accountAddr))},
|
|
||||||
|
|
||||||
// Policy capabilities
|
|
||||||
{Cap: caps.Cap(capability.CAPSETPOLICY.String()), Rsc: NewResource(resourcetype.RESPOLICY, fmt.Sprintf("%s:*", accountAddr))},
|
|
||||||
{Cap: caps.Cap(capability.CAPSETTHRESHOLD.String()), Rsc: NewResource(resourcetype.RESPOLICY, fmt.Sprintf("%s:threshold", accountAddr))},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewVaultPolicy creates attenuations for policy management
|
|
||||||
func NewVaultPolicy(
|
|
||||||
accountAddr string,
|
|
||||||
policyType policytype.PolicyType,
|
|
||||||
) Attenuations {
|
|
||||||
caps := VaultPermissions.GetCapabilities()
|
|
||||||
return Attenuations{
|
|
||||||
{
|
|
||||||
Cap: caps.Cap(capability.CAPSETPOLICY.String()),
|
|
||||||
Rsc: NewResource(
|
|
||||||
resourcetype.RESPOLICY,
|
|
||||||
fmt.Sprintf("%s:%s", accountAddr, policyType),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// VaultCapabilities defines the capability hierarchy
|
|
||||||
func VaultCapabilities() []string {
|
|
||||||
return []string{
|
|
||||||
CapOwner.String(),
|
|
||||||
CapOperator.String(),
|
|
||||||
CapObserver.String(),
|
|
||||||
CapAuthenticate.String(),
|
|
||||||
CapAuthorize.String(),
|
|
||||||
CapDelegate.String(),
|
|
||||||
CapInvoke.String(),
|
|
||||||
CapExecute.String(),
|
|
||||||
CapRecover.String(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+57
-18
@@ -1,27 +1,66 @@
|
|||||||
package ucan
|
package ucan
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CtxKey defines a distinct type for context keys used by the access
|
var EmptyAttenuation = Attenuation{
|
||||||
// package
|
Cap: Capability(nil),
|
||||||
type CtxKey string
|
Rsc: Resource(nil),
|
||||||
|
|
||||||
// TokenCtxKey is the key for adding an access UCAN to a context.Context
|
|
||||||
const TokenCtxKey CtxKey = "UCAN"
|
|
||||||
|
|
||||||
// CtxWithToken adds a UCAN value to a context
|
|
||||||
func CtxWithToken(ctx context.Context, t Token) context.Context {
|
|
||||||
return context.WithValue(ctx, TokenCtxKey, t)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FromCtx extracts a token from a given context if one is set, returning nil
|
// Permissions represents the type of attenuation
|
||||||
// otherwise
|
type Permissions string
|
||||||
func FromCtx(ctx context.Context) *Token {
|
|
||||||
iface := ctx.Value(TokenCtxKey)
|
const (
|
||||||
if ref, ok := iface.(*Token); ok {
|
// AccountPermissions represents the smart account attenuation
|
||||||
return ref
|
AccountPermissions = Permissions("account")
|
||||||
|
|
||||||
|
// ServicePermissions represents the service attenuation
|
||||||
|
ServicePermissions = Permissions("service")
|
||||||
|
|
||||||
|
// VaultPermissions represents the vault attenuation
|
||||||
|
VaultPermissions = Permissions("vault")
|
||||||
|
)
|
||||||
|
|
||||||
|
// Cap returns the capability for the given AttenuationPreset
|
||||||
|
func (a Permissions) NewCap(c string) Capability {
|
||||||
|
return a.GetCapabilities().Cap(c)
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
// NestedCapabilities returns the nested capabilities for the given AttenuationPreset
|
||||||
|
func (a Permissions) GetCapabilities() NestedCapabilities {
|
||||||
|
var caps []string
|
||||||
|
switch a {
|
||||||
|
case AccountPermissions:
|
||||||
|
// caps = SmartAccountCapabilities()
|
||||||
|
case VaultPermissions:
|
||||||
|
// caps = VaultCapabilities()
|
||||||
|
}
|
||||||
|
return NewNestedCapabilities(caps...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equals returns true if the given AttenuationPreset is equal to the receiver
|
||||||
|
func (a Permissions) Equals(b Permissions) bool {
|
||||||
|
return a == b
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the string representation of the AttenuationPreset
|
||||||
|
func (a Permissions) String() string {
|
||||||
|
return string(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseAttenuationData parses raw attenuation data into a structured format
|
||||||
|
func ParseAttenuationData(data map[string]interface{}) (Permissions, map[string]interface{}, error) {
|
||||||
|
typeRaw, ok := data["preset"]
|
||||||
|
if !ok {
|
||||||
|
return "", nil, fmt.Errorf("missing preset type in attenuation data")
|
||||||
|
}
|
||||||
|
|
||||||
|
presetType, ok := typeRaw.(string)
|
||||||
|
if !ok {
|
||||||
|
return "", nil, fmt.Errorf("invalid preset type format")
|
||||||
|
}
|
||||||
|
|
||||||
|
return Permissions(presetType), data, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,86 +0,0 @@
|
|||||||
package didkey
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p/core/crypto"
|
|
||||||
"github.com/onsonr/sonr/crypto/mpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestID_Parse(t *testing.T) {
|
|
||||||
keyStrED := "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH"
|
|
||||||
id, err := Parse(keyStrED)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if id.String() != keyStrED {
|
|
||||||
t.Errorf("string mismatch.\nwant: %q\ngot: %q", keyStrED, id.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
keyStrRSA := "did:key:z2MGw4gk84USotaWf4AkJ83DcnrfgGaceF86KQXRYMfQ7xqnUFp38UZ6Le8JPfkb4uCLGjHBzKpjEXb9hx9n2ftecQWCHXKtKszkke4FmENdTZ7i9sqRmL3pLnEEJ774r3HMuuC7tNRQ6pqzrxatXx2WinCibdhUmvh3FobnA9ygeqkSGtV6WLa7NVFw9cAvnv8Y6oHcaoZK7fNP4ASGs6AHmSC6ydSR676aKYMe95QmEAj4xJptDsSxG7zLAGzAdwCgm56M4fTno8GdWNmU6Pdghnuf6fWyYus9ASwdfwyaf3SDf4uo5T16PRJssHkQh6DJHfK4Rka7RNQLjzfGBPjFLHbUSvmf4EdbHasbVaveAArD68ZfazRCCvjdovQjWr6uyLCwSAQLPUFZBTT8mW"
|
|
||||||
|
|
||||||
id, err = Parse(keyStrRSA)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if id.String() != keyStrRSA {
|
|
||||||
t.Errorf("string mismatch.\nwant: %q\ngot: %q", keyStrRSA, id.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestID_FromMPCKey(t *testing.T) {
|
|
||||||
// Generate new MPC keyset
|
|
||||||
ks, err := mpc.NewKeyset()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to generate MPC keyset: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get public key from validator share
|
|
||||||
pubKey := ks.Val().PublicKey()
|
|
||||||
if len(pubKey) != 65 {
|
|
||||||
t.Fatalf("expected 65-byte uncompressed public key, got %d bytes", len(pubKey))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create crypto.PubKey from raw bytes
|
|
||||||
cryptoPubKey, err := crypto.UnmarshalSecp256k1PublicKey(pubKey)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to unmarshal public key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create DID Key ID
|
|
||||||
id, err := NewID(cryptoPubKey)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to create DID Key ID: %v", err)
|
|
||||||
}
|
|
||||||
log.Printf("%s\n", id.String())
|
|
||||||
|
|
||||||
// Verify the key can be parsed back
|
|
||||||
parsed, err := Parse(id.String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to parse DID Key string: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the parsed key matches original
|
|
||||||
if parsed.String() != id.String() {
|
|
||||||
t.Errorf("parsed key doesn't match original.\nwant: %q\ngot: %q",
|
|
||||||
id.String(), parsed.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify we can get back a valid verify key
|
|
||||||
verifyKey, err := id.VerifyKey()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to get verify key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify the key is the right type and length
|
|
||||||
rawKey, ok := verifyKey.([]byte)
|
|
||||||
if !ok {
|
|
||||||
t.Fatalf("expected []byte verify key, got %T", verifyKey)
|
|
||||||
}
|
|
||||||
if len(rawKey) != 65 && len(rawKey) != 33 {
|
|
||||||
t.Errorf("invalid key length %d, expected 65 or 33 bytes", len(rawKey))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,164 +0,0 @@
|
|||||||
package ucan
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/onsonr/sonr/crypto/ucan/attns/capability"
|
|
||||||
"github.com/onsonr/sonr/crypto/ucan/attns/policytype"
|
|
||||||
"github.com/onsonr/sonr/crypto/ucan/attns/resourcetype"
|
|
||||||
)
|
|
||||||
|
|
||||||
var EmptyAttenuation = Attenuation{
|
|
||||||
Cap: Capability(nil),
|
|
||||||
Rsc: Resource(nil),
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Owner
|
|
||||||
CapOwner = capability.CAPOWNER
|
|
||||||
CapOperator = capability.CAPOPERATOR
|
|
||||||
CapObserver = capability.CAPOBSERVER
|
|
||||||
|
|
||||||
// Auth
|
|
||||||
CapAuthenticate = capability.CAPAUTHENTICATE
|
|
||||||
CapAuthorize = capability.CAPAUTHORIZE
|
|
||||||
CapDelegate = capability.CAPDELEGATE
|
|
||||||
CapInvoke = capability.CAPINVOKE
|
|
||||||
CapExecute = capability.CAPEXECUTE
|
|
||||||
CapPropose = capability.CAPPROPOSE
|
|
||||||
CapSign = capability.CAPSIGN
|
|
||||||
CapSetPolicy = capability.CAPSETPOLICY
|
|
||||||
CapSetThreshold = capability.CAPSETTHRESHOLD
|
|
||||||
CapRecover = capability.CAPRECOVER
|
|
||||||
CapSocial = capability.CAPSOCIAL
|
|
||||||
CapResolver = capability.CAPRESOLVER
|
|
||||||
CapProducer = capability.CAPPRODUCER
|
|
||||||
|
|
||||||
// Resources
|
|
||||||
ResAccount = resourcetype.RESACCOUNT
|
|
||||||
ResTransaction = resourcetype.RESTRANSACTION
|
|
||||||
ResPolicy = resourcetype.RESPOLICY
|
|
||||||
ResRecovery = resourcetype.RESRECOVERY
|
|
||||||
ResVault = resourcetype.RESVAULT
|
|
||||||
ResIPFS = resourcetype.RESIPFS
|
|
||||||
ResIPNS = resourcetype.RESIPNS
|
|
||||||
ResKeyShare = resourcetype.RESKEYSHARE
|
|
||||||
|
|
||||||
// PolicyTypes
|
|
||||||
PolicyThreshold = policytype.POLICYTHRESHOLD
|
|
||||||
PolicyTimelock = policytype.POLICYTIMELOCK
|
|
||||||
PolicyWhitelist = policytype.POLICYWHITELIST
|
|
||||||
PolicyKeyShare = policytype.POLICYKEYGEN
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewVaultResource creates a new resource identifier
|
|
||||||
func NewResource(resType resourcetype.ResourceType, path string) Resource {
|
|
||||||
return NewStringLengthResource(string(resType), path)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Permissions represents the type of attenuation
|
|
||||||
type Permissions string
|
|
||||||
|
|
||||||
const (
|
|
||||||
// AccountPermissions represents the smart account attenuation
|
|
||||||
AccountPermissions = Permissions("account")
|
|
||||||
|
|
||||||
// ServicePermissions represents the service attenuation
|
|
||||||
ServicePermissions = Permissions("service")
|
|
||||||
|
|
||||||
// VaultPermissions represents the vault attenuation
|
|
||||||
VaultPermissions = Permissions("vault")
|
|
||||||
)
|
|
||||||
|
|
||||||
// Cap returns the capability for the given AttenuationPreset
|
|
||||||
func (a Permissions) NewCap(c capability.Capability) Capability {
|
|
||||||
return a.GetCapabilities().Cap(c.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
// NestedCapabilities returns the nested capabilities for the given AttenuationPreset
|
|
||||||
func (a Permissions) GetCapabilities() NestedCapabilities {
|
|
||||||
var caps []string
|
|
||||||
switch a {
|
|
||||||
case AccountPermissions:
|
|
||||||
caps = SmartAccountCapabilities()
|
|
||||||
case VaultPermissions:
|
|
||||||
caps = VaultCapabilities()
|
|
||||||
}
|
|
||||||
return NewNestedCapabilities(caps...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equals returns true if the given AttenuationPreset is equal to the receiver
|
|
||||||
func (a Permissions) Equals(b Permissions) bool {
|
|
||||||
return a == b
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the AttenuationPreset
|
|
||||||
func (a Permissions) String() string {
|
|
||||||
return string(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetConstructor returns the AttenuationConstructorFunc for a Permission
|
|
||||||
func (a Permissions) GetConstructor() AttenuationConstructorFunc {
|
|
||||||
return NewAttenuationFromPreset(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAttenuationFromPreset creates an AttenuationConstructorFunc for the given preset
|
|
||||||
func NewAttenuationFromPreset(preset Permissions) AttenuationConstructorFunc {
|
|
||||||
return func(v map[string]interface{}) (Attenuation, error) {
|
|
||||||
// Extract capability and resource from map
|
|
||||||
capStr, ok := v["cap"].(string)
|
|
||||||
if !ok {
|
|
||||||
return EmptyAttenuation, fmt.Errorf("missing or invalid capability in attenuation data")
|
|
||||||
}
|
|
||||||
|
|
||||||
resType, ok := v["type"].(string)
|
|
||||||
if !ok {
|
|
||||||
return EmptyAttenuation, fmt.Errorf("missing or invalid resource type in attenuation data")
|
|
||||||
}
|
|
||||||
|
|
||||||
path, ok := v["path"].(string)
|
|
||||||
if !ok {
|
|
||||||
path = "/" // Default path if not specified
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create capability from preset
|
|
||||||
cap := preset.NewCap(capability.Capability(capStr))
|
|
||||||
if cap == nil {
|
|
||||||
return EmptyAttenuation, fmt.Errorf("invalid capability %s for preset %s", capStr, preset)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create resource
|
|
||||||
resource := NewResource(resourcetype.ResourceType(resType), path)
|
|
||||||
|
|
||||||
return Attenuation{
|
|
||||||
Cap: cap,
|
|
||||||
Rsc: resource,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPresetConstructor returns the appropriate AttenuationConstructorFunc for a given type
|
|
||||||
func GetPresetConstructor(attType string) (AttenuationConstructorFunc, error) {
|
|
||||||
preset := Permissions(attType)
|
|
||||||
switch preset {
|
|
||||||
case AccountPermissions, ServicePermissions, VaultPermissions:
|
|
||||||
return NewAttenuationFromPreset(preset), nil
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unknown attenuation preset: %s", attType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseAttenuationData parses raw attenuation data into a structured format
|
|
||||||
func ParseAttenuationData(data map[string]interface{}) (Permissions, map[string]interface{}, error) {
|
|
||||||
typeRaw, ok := data["preset"]
|
|
||||||
if !ok {
|
|
||||||
return "", nil, fmt.Errorf("missing preset type in attenuation data")
|
|
||||||
}
|
|
||||||
|
|
||||||
presetType, ok := typeRaw.(string)
|
|
||||||
if !ok {
|
|
||||||
return "", nil, fmt.Errorf("invalid preset type format")
|
|
||||||
}
|
|
||||||
|
|
||||||
return Permissions(presetType), data, nil
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
package ucan
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestAttenuationPresetConstructor(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
data map[string]interface{}
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "valid smart account attenuation",
|
|
||||||
data: map[string]interface{}{
|
|
||||||
"preset": "account",
|
|
||||||
"cap": string(CapOwner),
|
|
||||||
"type": string(ResAccount),
|
|
||||||
"path": "/accounts/123",
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "valid vault attenuation",
|
|
||||||
data: map[string]interface{}{
|
|
||||||
"preset": "vault",
|
|
||||||
"cap": string(CapOperator),
|
|
||||||
"type": string(ResVault),
|
|
||||||
"path": "/vaults/456",
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
preset, data, err := ParseAttenuationData(tt.data)
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
constructor, err := GetPresetConstructor(preset.String())
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
attenuation, err := constructor(data)
|
|
||||||
if tt.wantErr {
|
|
||||||
assert.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.NotNil(t, attenuation)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
package spec
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/base64"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt"
|
|
||||||
"github.com/onsonr/sonr/crypto/mpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MPCSigningMethod implements the SigningMethod interface for MPC-based signing
|
|
||||||
type MPCSigningMethod struct {
|
|
||||||
Name string
|
|
||||||
ks ucanKeyshare
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewJWTSigningMethod creates a new MPC signing method with the given keyshare source
|
|
||||||
func NewJWTSigningMethod(name string, ks ucanKeyshare) *MPCSigningMethod {
|
|
||||||
return &MPCSigningMethod{
|
|
||||||
Name: name,
|
|
||||||
ks: ks,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alg returns the signing method's name
|
|
||||||
func (m *MPCSigningMethod) Alg() string {
|
|
||||||
return m.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify verifies the signature using the MPC public key
|
|
||||||
func (m *MPCSigningMethod) Verify(signingString, signature string, key interface{}) error {
|
|
||||||
// Decode the signature
|
|
||||||
sig, err := base64.RawURLEncoding.DecodeString(signature)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash the signing string
|
|
||||||
hasher := sha256.New()
|
|
||||||
hasher.Write([]byte(signingString))
|
|
||||||
digest := hasher.Sum(nil)
|
|
||||||
|
|
||||||
// Verify using the keyshare's public key
|
|
||||||
valid, err := mpc.VerifySignature(m.ks.valShare.PublicKey(), digest, sig)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to verify signature: %w", err)
|
|
||||||
}
|
|
||||||
if !valid {
|
|
||||||
return fmt.Errorf("invalid signature")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign signs the data using MPC
|
|
||||||
func (m *MPCSigningMethod) Sign(signingString string, key interface{}) (string, error) {
|
|
||||||
// Hash the signing string
|
|
||||||
hasher := sha256.New()
|
|
||||||
hasher.Write([]byte(signingString))
|
|
||||||
digest := hasher.Sum(nil)
|
|
||||||
|
|
||||||
// Create signing functions
|
|
||||||
signFunc, err := m.ks.userShare.SignFunc(digest)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to create sign function: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
valSignFunc, err := m.ks.valShare.SignFunc(digest)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to create validator sign function: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the signing protocol
|
|
||||||
sig, err := mpc.ExecuteSigning(valSignFunc, signFunc)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to run sign protocol: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serialize the signature
|
|
||||||
sigBytes, err := mpc.SerializeSignature(sig)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to serialize signature: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode the signature
|
|
||||||
encoded := base64.RawURLEncoding.EncodeToString(sigBytes)
|
|
||||||
return encoded, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// Register the MPC signing method
|
|
||||||
jwt.RegisterSigningMethod("MPC256", func() jwt.SigningMethod {
|
|
||||||
return &MPCSigningMethod{
|
|
||||||
Name: "MPC256",
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
+11
-11
@@ -21,7 +21,7 @@ import (
|
|||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/libp2p/go-libp2p/core/crypto"
|
"github.com/libp2p/go-libp2p/core/crypto"
|
||||||
mh "github.com/multiformats/go-multihash"
|
mh "github.com/multiformats/go-multihash"
|
||||||
"github.com/onsonr/sonr/crypto/ucan/didkey"
|
"github.com/onsonr/sonr/crypto/keys"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrInvalidToken indicates an access token is invalid
|
// ErrInvalidToken indicates an access token is invalid
|
||||||
@@ -47,8 +47,8 @@ const (
|
|||||||
type Token struct {
|
type Token struct {
|
||||||
// Entire UCAN as a signed JWT string
|
// Entire UCAN as a signed JWT string
|
||||||
Raw string
|
Raw string
|
||||||
Issuer didkey.ID
|
Issuer keys.DID
|
||||||
Audience didkey.ID
|
Audience keys.DID
|
||||||
// the "inputs" to this token, a chain UCAN tokens with broader scopes &
|
// the "inputs" to this token, a chain UCAN tokens with broader scopes &
|
||||||
// deadlines than this token
|
// deadlines than this token
|
||||||
Proofs []Proof `json:"prf,omitempty"`
|
Proofs []Proof `json:"prf,omitempty"`
|
||||||
@@ -261,12 +261,12 @@ func (a *pkSource) newToken(audienceDID string, prf []Proof, att Attenuations, f
|
|||||||
// DIDPubKeyResolver turns did:key Decentralized IDentifiers into a public key,
|
// DIDPubKeyResolver turns did:key Decentralized IDentifiers into a public key,
|
||||||
// possibly using a network request
|
// possibly using a network request
|
||||||
type DIDPubKeyResolver interface {
|
type DIDPubKeyResolver interface {
|
||||||
ResolveDIDKey(ctx context.Context, did string) (didkey.ID, error)
|
ResolveDIDKey(ctx context.Context, did string) (keys.DID, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DIDStringFromPublicKey creates a did:key identifier string from a public key
|
// DIDStringFromPublicKey creates a did:key identifier string from a public key
|
||||||
func DIDStringFromPublicKey(pub crypto.PubKey) (string, error) {
|
func DIDStringFromPublicKey(pub crypto.PubKey) (string, error) {
|
||||||
id, err := didkey.NewID(pub)
|
id, err := keys.NewDID(pub)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -279,8 +279,8 @@ func DIDStringFromPublicKey(pub crypto.PubKey) (string, error) {
|
|||||||
type StringDIDPubKeyResolver struct{}
|
type StringDIDPubKeyResolver struct{}
|
||||||
|
|
||||||
// ResolveDIDKey extracts a public key from a did:key string
|
// ResolveDIDKey extracts a public key from a did:key string
|
||||||
func (StringDIDPubKeyResolver) ResolveDIDKey(ctx context.Context, didStr string) (didkey.ID, error) {
|
func (StringDIDPubKeyResolver) ResolveDIDKey(ctx context.Context, didStr string) (keys.DID, error) {
|
||||||
return didkey.Parse(didStr)
|
return keys.Parse(didStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TokenParser parses a raw string into a Token
|
// TokenParser parses a raw string into a Token
|
||||||
@@ -315,11 +315,11 @@ func (p *TokenParser) parseAndVerify(ctx context.Context, raw string, child *Tok
|
|||||||
return nil, fmt.Errorf("parser fail")
|
return nil, fmt.Errorf("parser fail")
|
||||||
}
|
}
|
||||||
|
|
||||||
var iss didkey.ID
|
var iss keys.DID
|
||||||
// TODO(b5): we're double parsing here b/c the jwt lib we're using doesn't expose
|
// TODO(b5): we're double parsing here b/c the jwt lib we're using doesn't expose
|
||||||
// an API (that I know of) for storing parsed issuer / audience
|
// an API (that I know of) for storing parsed issuer / audience
|
||||||
if issStr, ok := mc["iss"].(string); ok {
|
if issStr, ok := mc["iss"].(string); ok {
|
||||||
iss, err = didkey.Parse(issStr)
|
iss, err = keys.Parse(issStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -327,11 +327,11 @@ func (p *TokenParser) parseAndVerify(ctx context.Context, raw string, child *Tok
|
|||||||
return nil, fmt.Errorf(`"iss" key is not in claims`)
|
return nil, fmt.Errorf(`"iss" key is not in claims`)
|
||||||
}
|
}
|
||||||
|
|
||||||
var aud didkey.ID
|
var aud keys.DID
|
||||||
// TODO(b5): we're double parsing here b/c the jwt lib we're using doesn't expose
|
// TODO(b5): we're double parsing here b/c the jwt lib we're using doesn't expose
|
||||||
// an API (that I know of) for storing parsed issuer / audience
|
// an API (that I know of) for storing parsed issuer / audience
|
||||||
if audStr, ok := mc["aud"].(string); ok {
|
if audStr, ok := mc["aud"].(string); ok {
|
||||||
aud, err = didkey.Parse(audStr)
|
aud, err = keys.Parse(audStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
# https://taskfile.dev
|
|
||||||
|
|
||||||
version: "3"
|
|
||||||
|
|
||||||
vars:
|
|
||||||
GREETING: Hello, World!
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
init:sonrd:
|
|
||||||
cmds:
|
|
||||||
- sonrd init {{.NODE_NAME}} --chain-id {{.CHAIN_ID}} --home {{.HOME}}
|
|
||||||
|
|
||||||
init:ipfs:
|
|
||||||
cmds:
|
|
||||||
- ipfs init
|
|
||||||
|
|
||||||
init:hway:
|
|
||||||
cmds:
|
|
||||||
- sonrd hway init {{.NODE_NAME}} --home {{.HOME}}
|
|
||||||
|
|
||||||
start:sonrd:
|
|
||||||
cmds:
|
|
||||||
- sonrd start --home {{.HOME}}
|
|
||||||
|
|
||||||
start:ipfs:
|
|
||||||
cmds:
|
|
||||||
- ipfs daemon
|
|
||||||
|
|
||||||
start:hway:
|
|
||||||
cmds:
|
|
||||||
- sonrd hway start --home {{.HOME}}
|
|
||||||
|
|
||||||
stop:sonrd:
|
|
||||||
cmds:
|
|
||||||
- sonrd stop
|
|
||||||
|
|
||||||
stop:ipfs:
|
|
||||||
cmds:
|
|
||||||
- ipfs daemon stop
|
|
||||||
|
|
||||||
stop:hway:
|
|
||||||
cmds:
|
|
||||||
- sonrd hway stop
|
|
||||||
|
|
||||||
clean:sonrd:
|
|
||||||
cmds:
|
|
||||||
- rm -rf {{.HOME}}
|
|
||||||
|
|
||||||
clean:ipfs:
|
|
||||||
cmds:
|
|
||||||
- rm -rf ~/.ipfs
|
|
||||||
|
|
||||||
clean:hway:
|
|
||||||
cmds:
|
|
||||||
- rm -rf {{.HOME}}/data/hway
|
|
||||||
@@ -1,251 +0,0 @@
|
|||||||
{
|
|
||||||
"lockfile_version": "1",
|
|
||||||
"packages": {
|
|
||||||
"air@latest": {
|
|
||||||
"last_modified": "2024-11-16T04:25:12Z",
|
|
||||||
"resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#air",
|
|
||||||
"source": "devbox-search",
|
|
||||||
"version": "1.61.1",
|
|
||||||
"systems": {
|
|
||||||
"aarch64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/0s90vbnmsyyixs0991md21pbrw8babfb-air-1.61.1",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/0s90vbnmsyyixs0991md21pbrw8babfb-air-1.61.1"
|
|
||||||
},
|
|
||||||
"aarch64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/8mpw2asxs297v26fxqy2y1bq438f344l-air-1.61.1",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/8mpw2asxs297v26fxqy2y1bq438f344l-air-1.61.1"
|
|
||||||
},
|
|
||||||
"x86_64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/abminkf7ldqf9vm14xx5wvsrdx3wrvy6-air-1.61.1",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/abminkf7ldqf9vm14xx5wvsrdx3wrvy6-air-1.61.1"
|
|
||||||
},
|
|
||||||
"x86_64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/ajx8v5rbbvglncb97yybg3x9kn95gfrm-air-1.61.1",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/ajx8v5rbbvglncb97yybg3x9kn95gfrm-air-1.61.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"bun@latest": {
|
|
||||||
"last_modified": "2024-11-18T00:41:09Z",
|
|
||||||
"resolved": "github:NixOS/nixpkgs/5083ec887760adfe12af64830a66807423a859a7#bun",
|
|
||||||
"source": "devbox-search",
|
|
||||||
"version": "1.1.34",
|
|
||||||
"systems": {
|
|
||||||
"aarch64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/xnj00gq1mfffvgyisghk4m9f38gc5c5c-bun-1.1.34",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/xnj00gq1mfffvgyisghk4m9f38gc5c5c-bun-1.1.34"
|
|
||||||
},
|
|
||||||
"aarch64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/kccpzv8fb7swmmxbhv805qzq242rhy33-bun-1.1.34",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/kccpzv8fb7swmmxbhv805qzq242rhy33-bun-1.1.34"
|
|
||||||
},
|
|
||||||
"x86_64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/8h5k3l4fpgs3al2wvna7x9ybyyc8k36d-bun-1.1.34",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/8h5k3l4fpgs3al2wvna7x9ybyyc8k36d-bun-1.1.34"
|
|
||||||
},
|
|
||||||
"x86_64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/x089g4srqw71w5jnc87vxbh7m12498i0-bun-1.1.34",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/x089g4srqw71w5jnc87vxbh7m12498i0-bun-1.1.34"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ipfs@latest": {
|
|
||||||
"last_modified": "2023-02-24T09:01:09Z",
|
|
||||||
"resolved": "github:NixOS/nixpkgs/7d0ed7f2e5aea07ab22ccb338d27fbe347ed2f11#ipfs",
|
|
||||||
"source": "devbox-search",
|
|
||||||
"version": "0.17.0"
|
|
||||||
},
|
|
||||||
"skate@latest": {
|
|
||||||
"last_modified": "2024-11-16T04:25:12Z",
|
|
||||||
"resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#skate",
|
|
||||||
"source": "devbox-search",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"systems": {
|
|
||||||
"aarch64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/q6yhpyfbqiabyic6ymx5rp2db62bnbvr-skate-1.0.0",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/q6yhpyfbqiabyic6ymx5rp2db62bnbvr-skate-1.0.0"
|
|
||||||
},
|
|
||||||
"aarch64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/q55dbgvc4xwvr2g02dks6j2j699qni2k-skate-1.0.0",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/q55dbgvc4xwvr2g02dks6j2j699qni2k-skate-1.0.0"
|
|
||||||
},
|
|
||||||
"x86_64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/s1hy525y8ciya3nrns9kryy3jlcw8igv-skate-1.0.0",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/s1hy525y8ciya3nrns9kryy3jlcw8igv-skate-1.0.0"
|
|
||||||
},
|
|
||||||
"x86_64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/8s03iazymz77nv6pjxpz7wair0m646wv-skate-1.0.0",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/8s03iazymz77nv6pjxpz7wair0m646wv-skate-1.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"templ@latest": {
|
|
||||||
"last_modified": "2024-11-16T04:25:12Z",
|
|
||||||
"resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#templ",
|
|
||||||
"source": "devbox-search",
|
|
||||||
"version": "0.2.793",
|
|
||||||
"systems": {
|
|
||||||
"aarch64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/ivargvf76g71k5gk3iz4al52rsy28w38-templ-0.2.793",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/ivargvf76g71k5gk3iz4al52rsy28w38-templ-0.2.793"
|
|
||||||
},
|
|
||||||
"aarch64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/03654iddn006yx5j1lqq496hax60v8p5-templ-0.2.793",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/03654iddn006yx5j1lqq496hax60v8p5-templ-0.2.793"
|
|
||||||
},
|
|
||||||
"x86_64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/blvd5wbd1ix6m745s4zx3b84kwzprshq-templ-0.2.793",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/blvd5wbd1ix6m745s4zx3b84kwzprshq-templ-0.2.793"
|
|
||||||
},
|
|
||||||
"x86_64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/sn5h79d36r86i6a8rm1k52c2ij1s32kx-templ-0.2.793",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/sn5h79d36r86i6a8rm1k52c2ij1s32kx-templ-0.2.793"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tigerbeetle@latest": {
|
|
||||||
"last_modified": "2024-11-16T04:25:12Z",
|
|
||||||
"resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#tigerbeetle",
|
|
||||||
"source": "devbox-search",
|
|
||||||
"version": "0.16.12",
|
|
||||||
"systems": {
|
|
||||||
"aarch64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/mm3jzwf24p35afr55v7kl5a0h6962i6p-tigerbeetle-0.16.12",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/mm3jzwf24p35afr55v7kl5a0h6962i6p-tigerbeetle-0.16.12"
|
|
||||||
},
|
|
||||||
"aarch64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/4106973gg3crfxq0gwrgwn4hcx64mzyy-tigerbeetle-0.16.12",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/4106973gg3crfxq0gwrgwn4hcx64mzyy-tigerbeetle-0.16.12"
|
|
||||||
},
|
|
||||||
"x86_64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/6lnwnr3mvdamm5lxjjqkaagw2pyqlq0a-tigerbeetle-0.16.12",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/6lnwnr3mvdamm5lxjjqkaagw2pyqlq0a-tigerbeetle-0.16.12"
|
|
||||||
},
|
|
||||||
"x86_64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/afrj2ph61xz0lh7f3d1g1d7v2rslbvny-tigerbeetle-0.16.12",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/afrj2ph61xz0lh7f3d1g1d7v2rslbvny-tigerbeetle-0.16.12"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,16 +3,10 @@ version: "0.6"
|
|||||||
processes:
|
processes:
|
||||||
sonr:
|
sonr:
|
||||||
namespace: devnet
|
namespace: devnet
|
||||||
background: true
|
|
||||||
command: "make sh-testnet"
|
command: "make sh-testnet"
|
||||||
restart: never
|
|
||||||
max_restarts: 1
|
|
||||||
|
|
||||||
hway:
|
hway:
|
||||||
namespace: devnet
|
namespace: devnet
|
||||||
background: true
|
|
||||||
command: "./build/hway"
|
command: "./build/hway"
|
||||||
restart: never
|
|
||||||
max_restarts: 1
|
|
||||||
depends:
|
depends:
|
||||||
- sonr
|
- sonr
|
||||||
@@ -1,202 +0,0 @@
|
|||||||
import "https://pkl.sh/ipfs.net/0.0.1/Config.pkl"
|
|
||||||
|
|
||||||
API {
|
|
||||||
HTTPHeaders {
|
|
||||||
`Access-Control-Allow-Origin` = new { "*" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Addresses {
|
|
||||||
API = "/ip4/127.0.0.1/tcp/5001"
|
|
||||||
Gateway = "/ip4/127.0.0.1/tcp/8080"
|
|
||||||
Swarm = new {
|
|
||||||
"/ip4/0.0.0.0/tcp/4001"
|
|
||||||
"/ip6/::/tcp/4001"
|
|
||||||
"/ip4/0.0.0.0/udp/4001/quic"
|
|
||||||
"/ip6/::/udp/4001/quic"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Bootstrap {
|
|
||||||
"/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa"
|
|
||||||
"/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb"
|
|
||||||
"/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt"
|
|
||||||
"/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ"
|
|
||||||
"/ip4/104.131.131.82/udp/4001/quic/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ"
|
|
||||||
"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN"
|
|
||||||
}
|
|
||||||
|
|
||||||
Datastore {
|
|
||||||
BloomFilterSize = 0
|
|
||||||
GCPeriod = "1h"
|
|
||||||
HashOnRead = false
|
|
||||||
StorageGCWatermark = 90
|
|
||||||
StorageMax = "10GB"
|
|
||||||
Spec = new {
|
|
||||||
mounts = new {
|
|
||||||
new {
|
|
||||||
prefix = "flatfs.datastore"
|
|
||||||
child = new {
|
|
||||||
path = "blocks"
|
|
||||||
shardFunc = "/repo/flatfs/shard/v1/next-to-last/2"
|
|
||||||
type = "flatfs"
|
|
||||||
sync = true
|
|
||||||
}
|
|
||||||
mountpoint = "/blocks"
|
|
||||||
type = "measure"
|
|
||||||
}
|
|
||||||
new {
|
|
||||||
prefix = "leveldb.datastore"
|
|
||||||
child = new {
|
|
||||||
compression = "none"
|
|
||||||
path = "datastore"
|
|
||||||
type = "levelds"
|
|
||||||
}
|
|
||||||
mountpoint = "/"
|
|
||||||
type = "measure"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
type = "mount"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Discovery {
|
|
||||||
MDNS = new {
|
|
||||||
Enabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Experimental {
|
|
||||||
StrategicProviding = false
|
|
||||||
UrlstoreEnabled = false
|
|
||||||
AcceleratedDHTClient = false
|
|
||||||
GraphsyncEnabled = false
|
|
||||||
FilestoreEnabled = false
|
|
||||||
Libp2pStreamMounting = false
|
|
||||||
P2pHttpProxy = false
|
|
||||||
}
|
|
||||||
|
|
||||||
Gateway {
|
|
||||||
HTTPHeaders = new {
|
|
||||||
`Access-Control-Allow-Headers` = new {
|
|
||||||
"X-Requested-With"
|
|
||||||
"Range"
|
|
||||||
"User-Agent"
|
|
||||||
}
|
|
||||||
`Access-Control-Allow-Methods` = new { "GET" }
|
|
||||||
`Access-Control-Allow-Origin` = new { "*" }
|
|
||||||
}
|
|
||||||
NoDNSLink = false
|
|
||||||
NoFetch = false
|
|
||||||
PublicGateways = null
|
|
||||||
RootRedirect = ""
|
|
||||||
Writable = false
|
|
||||||
}
|
|
||||||
|
|
||||||
Identity {
|
|
||||||
PrivKey = "CAESQP0FRhYf5Nvxg0wrbN+VTK7kWdgy+3AKoxU3vNH0K9FHVpXyx6/mHKyCaPjqI11YsHUW0B2ZODGROPafyS6IeWY="
|
|
||||||
PeerID = "12D3KooWFeMr1tHFs8WAF11rKDULJbmKg9rE5aVhYJU23oC7pqjB"
|
|
||||||
}
|
|
||||||
|
|
||||||
Ipns {
|
|
||||||
RecordLifetime = ""
|
|
||||||
RepublishPeriod = ""
|
|
||||||
ResolveCacheSize = 128
|
|
||||||
}
|
|
||||||
|
|
||||||
Migration {
|
|
||||||
Keep = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
Mounts {
|
|
||||||
IPNS = "/ipns"
|
|
||||||
FuseAllowOther = false
|
|
||||||
IPFS = "/ipfs"
|
|
||||||
}
|
|
||||||
|
|
||||||
Peering {
|
|
||||||
Peers = new {
|
|
||||||
new {
|
|
||||||
Addrs = new { "/dnsaddr/node-1.ingress.cloudflare-ipfs.com" }
|
|
||||||
ID = "QmcFf2FH3CEgTNHeMRGhN7HNHU1EXAxoEk6EFuSyXCsvRE"
|
|
||||||
}
|
|
||||||
new {
|
|
||||||
Addrs = new { "/dnsaddr/node-2.ingress.cloudflare-ipfs.com" }
|
|
||||||
ID = "QmcFmLd5ySfk2WZuJ1mfSWLDjdmHZq7rSAua4GoeSQfs1z"
|
|
||||||
}
|
|
||||||
new {
|
|
||||||
Addrs = new { "/dnsaddr/node-3.ingress.cloudflare-ipfs.com" }
|
|
||||||
ID = "QmcfFmzSDVbwexQ9Au2pt5YEXHK5xajwgaU6PpkbLWerMa"
|
|
||||||
}
|
|
||||||
new {
|
|
||||||
Addrs = new { "/dnsaddr/node-4.ingress.cloudflare-ipfs.com" }
|
|
||||||
ID = "QmcfJeB3Js1FG7T8YaZATEiaHqNKVdQfybYYkbT1knUswx"
|
|
||||||
}
|
|
||||||
new {
|
|
||||||
Addrs = new { "/dnsaddr/node-5.ingress.cloudflare-ipfs.com" }
|
|
||||||
ID = "QmcfVvzK4tMdFmpJjEKDUoqRgP4W9FnmJoziYX5GXJJ8eZ"
|
|
||||||
}
|
|
||||||
new {
|
|
||||||
Addrs = new { "/dnsaddr/node-6.ingress.cloudflare-ipfs.com" }
|
|
||||||
ID = "QmcfZD3VKrUxyP9BbyUnZDpbqDnT7cQ4WjPP8TRLXaoE7G"
|
|
||||||
}
|
|
||||||
new {
|
|
||||||
Addrs = new { "/dnsaddr/node-7.ingress.cloudflare-ipfs.com" }
|
|
||||||
ID = "QmcfZP2LuW4jxviTeG8fi28qjnZScACb8PEgHAc17ZEri3"
|
|
||||||
}
|
|
||||||
new {
|
|
||||||
Addrs = new { "/dnsaddr/node-8.ingress.cloudflare-ipfs.com" }
|
|
||||||
ID = "QmcfgsJsMtx6qJb74akCw1M24X1zFwgGo11h1cuhwQjtJP"
|
|
||||||
}
|
|
||||||
new {
|
|
||||||
Addrs = new { "/dnsaddr/node-9.ingress.cloudflare-ipfs.com" }
|
|
||||||
ID = "Qmcfr2FC7pFzJbTSDfYaSy1J8Uuy8ccGLeLyqJCKJvTHMi"
|
|
||||||
}
|
|
||||||
new {
|
|
||||||
Addrs = new { "/dnsaddr/node-10.ingress.cloudflare-ipfs.com" }
|
|
||||||
ID = "QmcfR3V5YAtHBzxVACWCzXTt26SyEkxdwhGJ6875A8BuWx"
|
|
||||||
}
|
|
||||||
new {
|
|
||||||
Addrs = new { "/dnsaddr/node-11.ingress.cloudflare-ipfs.com" }
|
|
||||||
ID = "Qmcfuo1TM9uUiJp6dTbm915Rf1aTqm3a3dnmCdDQLHgvL5"
|
|
||||||
}
|
|
||||||
new {
|
|
||||||
Addrs = new { "/dnsaddr/node-12.ingress.cloudflare-ipfs.com" }
|
|
||||||
ID = "QmcfV2sg9zaq7UUHVCGuSvT2M2rnLBAPsiE79vVyK3Cuev"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Provider {
|
|
||||||
Strategy = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
Pubsub {
|
|
||||||
Router = ""
|
|
||||||
DisableSigning = false
|
|
||||||
}
|
|
||||||
|
|
||||||
Reprovider {
|
|
||||||
Strategy = "all"
|
|
||||||
Interval = "12h"
|
|
||||||
}
|
|
||||||
|
|
||||||
Routing {
|
|
||||||
Methods = null
|
|
||||||
Routers = null
|
|
||||||
Type = "dht"
|
|
||||||
}
|
|
||||||
|
|
||||||
Swarm {
|
|
||||||
AddrFilters = null
|
|
||||||
ConnMgr = new {}
|
|
||||||
DisableBandwidthMetrics = false
|
|
||||||
DisableNatPortMap = false
|
|
||||||
RelayClient = new {}
|
|
||||||
ResourceMgr = new {}
|
|
||||||
Transports = new {
|
|
||||||
Multiplexers = new {}
|
|
||||||
Network = new {}
|
|
||||||
Security = new {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
amends "https://pkl.sh/sonr.chain/0.0.2/App.pkl"
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
amends "https://pkl.sh/sonr.chain/0.0.2/Genesis.pkl"
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,404 +0,0 @@
|
|||||||
{
|
|
||||||
"lockfile_version": "1",
|
|
||||||
"packages": {
|
|
||||||
"bun@latest": {
|
|
||||||
"last_modified": "2024-11-18T00:41:09Z",
|
|
||||||
"resolved": "github:NixOS/nixpkgs/5083ec887760adfe12af64830a66807423a859a7#bun",
|
|
||||||
"source": "devbox-search",
|
|
||||||
"version": "1.1.34",
|
|
||||||
"systems": {
|
|
||||||
"aarch64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/xnj00gq1mfffvgyisghk4m9f38gc5c5c-bun-1.1.34",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/xnj00gq1mfffvgyisghk4m9f38gc5c5c-bun-1.1.34"
|
|
||||||
},
|
|
||||||
"aarch64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/kccpzv8fb7swmmxbhv805qzq242rhy33-bun-1.1.34",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/kccpzv8fb7swmmxbhv805qzq242rhy33-bun-1.1.34"
|
|
||||||
},
|
|
||||||
"x86_64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/8h5k3l4fpgs3al2wvna7x9ybyyc8k36d-bun-1.1.34",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/8h5k3l4fpgs3al2wvna7x9ybyyc8k36d-bun-1.1.34"
|
|
||||||
},
|
|
||||||
"x86_64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/x089g4srqw71w5jnc87vxbh7m12498i0-bun-1.1.34",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/x089g4srqw71w5jnc87vxbh7m12498i0-bun-1.1.34"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"cloudflared@latest": {
|
|
||||||
"last_modified": "2024-11-18T00:41:09Z",
|
|
||||||
"resolved": "github:NixOS/nixpkgs/5083ec887760adfe12af64830a66807423a859a7#cloudflared",
|
|
||||||
"source": "devbox-search",
|
|
||||||
"version": "2024.11.0",
|
|
||||||
"systems": {
|
|
||||||
"aarch64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/95knk04xlh78swlk9a6kg524rfykzzmz-cloudflared-2024.11.0",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/95knk04xlh78swlk9a6kg524rfykzzmz-cloudflared-2024.11.0"
|
|
||||||
},
|
|
||||||
"aarch64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/2d6mh1pi99m19bc9m3phcsfgygbfpyig-cloudflared-2024.11.0",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/2d6mh1pi99m19bc9m3phcsfgygbfpyig-cloudflared-2024.11.0"
|
|
||||||
},
|
|
||||||
"x86_64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/4dii539ldfv0f9n7xigfy19ivrg3ng2n-cloudflared-2024.11.0",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/4dii539ldfv0f9n7xigfy19ivrg3ng2n-cloudflared-2024.11.0"
|
|
||||||
},
|
|
||||||
"x86_64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/hlnabpfi58mpd16symqb7kp8xc2lf1pf-cloudflared-2024.11.0",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/hlnabpfi58mpd16symqb7kp8xc2lf1pf-cloudflared-2024.11.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"go@1.23": {
|
|
||||||
"last_modified": "2024-11-16T04:25:12Z",
|
|
||||||
"resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#go",
|
|
||||||
"source": "devbox-search",
|
|
||||||
"version": "1.23.3",
|
|
||||||
"systems": {
|
|
||||||
"aarch64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/qrj2wp6vzfpjfrrlcmr22818zg83fb73-go-1.23.3",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/qrj2wp6vzfpjfrrlcmr22818zg83fb73-go-1.23.3"
|
|
||||||
},
|
|
||||||
"aarch64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/dm66qyl19skrwcmk4rb9xcs64xc1d071-go-1.23.3",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/dm66qyl19skrwcmk4rb9xcs64xc1d071-go-1.23.3"
|
|
||||||
},
|
|
||||||
"x86_64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/vkjn6njpz4gy5ma763vh8hh93bgjwycr-go-1.23.3",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/vkjn6njpz4gy5ma763vh8hh93bgjwycr-go-1.23.3"
|
|
||||||
},
|
|
||||||
"x86_64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/bavnchxi7v6xs077jxv7fl5rrqc3y87w-go-1.23.3",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/bavnchxi7v6xs077jxv7fl5rrqc3y87w-go-1.23.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ipfs@latest": {
|
|
||||||
"last_modified": "2023-02-24T09:01:09Z",
|
|
||||||
"resolved": "github:NixOS/nixpkgs/7d0ed7f2e5aea07ab22ccb338d27fbe347ed2f11#ipfs",
|
|
||||||
"source": "devbox-search",
|
|
||||||
"version": "0.17.0"
|
|
||||||
},
|
|
||||||
"matrix-synapse@latest": {
|
|
||||||
"last_modified": "2024-11-18T00:41:09Z",
|
|
||||||
"resolved": "github:NixOS/nixpkgs/5083ec887760adfe12af64830a66807423a859a7#matrix-synapse",
|
|
||||||
"source": "devbox-search",
|
|
||||||
"version": "1.119.0",
|
|
||||||
"systems": {
|
|
||||||
"aarch64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/dfgj6lgmxy18qd5v9z91376i0b1z06jx-matrix-synapse-wrapped-1.119.0",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/dfgj6lgmxy18qd5v9z91376i0b1z06jx-matrix-synapse-wrapped-1.119.0"
|
|
||||||
},
|
|
||||||
"x86_64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/570l35c4n3qdxaszrf6bz4rrrw87pkil-matrix-synapse-wrapped-1.119.0",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/570l35c4n3qdxaszrf6bz4rrrw87pkil-matrix-synapse-wrapped-1.119.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"postgresql@latest": {
|
|
||||||
"last_modified": "2024-11-22T01:27:12Z",
|
|
||||||
"plugin_version": "0.0.2",
|
|
||||||
"resolved": "github:NixOS/nixpkgs/8edf06bea5bcbee082df1b7369ff973b91618b8d#postgresql",
|
|
||||||
"source": "devbox-search",
|
|
||||||
"version": "16.4",
|
|
||||||
"systems": {
|
|
||||||
"aarch64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/j6n9b877yhrnkp9z9p1gllxpnfvdrbrb-postgresql-16.4",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "man",
|
|
||||||
"path": "/nix/store/465icqyw6m38jxpx5yr1ri26ki0f96sz-postgresql-16.4-man",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "lib",
|
|
||||||
"path": "/nix/store/l9w6d22hrcrxkv005g2gbzhvk64vp4rm-postgresql-16.4-lib"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "dev",
|
|
||||||
"path": "/nix/store/jvw9nsblsbh9m4n551sq7qnw82hhsv08-postgresql-16.4-dev"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "doc",
|
|
||||||
"path": "/nix/store/fk1x8k1qsiaasp73qnzyrzw4ylaf1xy6-postgresql-16.4-doc"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/j6n9b877yhrnkp9z9p1gllxpnfvdrbrb-postgresql-16.4"
|
|
||||||
},
|
|
||||||
"aarch64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/2ywn472iqfdiyw5w4frm63rn3nyrkgn1-postgresql-16.4",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "man",
|
|
||||||
"path": "/nix/store/650fqsb195p9x00jgqgzkisjwddbvgfd-postgresql-16.4-man",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "debug",
|
|
||||||
"path": "/nix/store/wm34pd2y04mjgvhanqw4ymmhds56l9da-postgresql-16.4-debug"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "dev",
|
|
||||||
"path": "/nix/store/ai2ckvi44jdh9i5078gj5brdwsxk4ydm-postgresql-16.4-dev"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "doc",
|
|
||||||
"path": "/nix/store/qys6z2y4iwr0f6ahpq9gcv9hb551w479-postgresql-16.4-doc"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "lib",
|
|
||||||
"path": "/nix/store/pii1vyxbzggi7aqy7xglav8p52c0qfp2-postgresql-16.4-lib"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/2ywn472iqfdiyw5w4frm63rn3nyrkgn1-postgresql-16.4"
|
|
||||||
},
|
|
||||||
"x86_64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/5k1p2jjnsdcsvk8zpsqxlzhajh1x9ghq-postgresql-16.4",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "man",
|
|
||||||
"path": "/nix/store/p8b24icm7xiwlky1dggqcinn1ah92agl-postgresql-16.4-man",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "dev",
|
|
||||||
"path": "/nix/store/cvl9wdw387jk02bbhm1qvidzl18hayyr-postgresql-16.4-dev"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "doc",
|
|
||||||
"path": "/nix/store/ysmwxhh3s2l1k2jkzxq0bv6vdzlgr14j-postgresql-16.4-doc"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "lib",
|
|
||||||
"path": "/nix/store/4va0gp1c718dk1zyqs0il2gn7a81spr0-postgresql-16.4-lib"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/5k1p2jjnsdcsvk8zpsqxlzhajh1x9ghq-postgresql-16.4"
|
|
||||||
},
|
|
||||||
"x86_64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/ypx0whdqvwbql73nija0zrm4z3rgcm9l-postgresql-16.4",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "man",
|
|
||||||
"path": "/nix/store/7x75jfmpc7x36863cf6kr61ikcz787ki-postgresql-16.4-man",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "doc",
|
|
||||||
"path": "/nix/store/4c7h8sg2i0jim6hzmzhjw5nn0zmx1xvd-postgresql-16.4-doc"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "lib",
|
|
||||||
"path": "/nix/store/xd8ks7bs2p7gjgk8h98bfg8801swl9m0-postgresql-16.4-lib"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "debug",
|
|
||||||
"path": "/nix/store/pxhd0wq2sbafamjmcp7f890qza76gwav-postgresql-16.4-debug"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "dev",
|
|
||||||
"path": "/nix/store/20i6jma3fbm4sw060hdnrs311fw4aczj-postgresql-16.4-dev"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/ypx0whdqvwbql73nija0zrm4z3rgcm9l-postgresql-16.4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"skate@latest": {
|
|
||||||
"last_modified": "2024-11-16T04:25:12Z",
|
|
||||||
"resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#skate",
|
|
||||||
"source": "devbox-search",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"systems": {
|
|
||||||
"aarch64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/q6yhpyfbqiabyic6ymx5rp2db62bnbvr-skate-1.0.0",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/q6yhpyfbqiabyic6ymx5rp2db62bnbvr-skate-1.0.0"
|
|
||||||
},
|
|
||||||
"aarch64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/q55dbgvc4xwvr2g02dks6j2j699qni2k-skate-1.0.0",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/q55dbgvc4xwvr2g02dks6j2j699qni2k-skate-1.0.0"
|
|
||||||
},
|
|
||||||
"x86_64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/s1hy525y8ciya3nrns9kryy3jlcw8igv-skate-1.0.0",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/s1hy525y8ciya3nrns9kryy3jlcw8igv-skate-1.0.0"
|
|
||||||
},
|
|
||||||
"x86_64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/8s03iazymz77nv6pjxpz7wair0m646wv-skate-1.0.0",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/8s03iazymz77nv6pjxpz7wair0m646wv-skate-1.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tigerbeetle@latest": {
|
|
||||||
"last_modified": "2024-11-16T04:25:12Z",
|
|
||||||
"resolved": "github:NixOS/nixpkgs/34a626458d686f1b58139620a8b2793e9e123bba#tigerbeetle",
|
|
||||||
"source": "devbox-search",
|
|
||||||
"version": "0.16.12",
|
|
||||||
"systems": {
|
|
||||||
"aarch64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/mm3jzwf24p35afr55v7kl5a0h6962i6p-tigerbeetle-0.16.12",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/mm3jzwf24p35afr55v7kl5a0h6962i6p-tigerbeetle-0.16.12"
|
|
||||||
},
|
|
||||||
"aarch64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/4106973gg3crfxq0gwrgwn4hcx64mzyy-tigerbeetle-0.16.12",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/4106973gg3crfxq0gwrgwn4hcx64mzyy-tigerbeetle-0.16.12"
|
|
||||||
},
|
|
||||||
"x86_64-darwin": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/6lnwnr3mvdamm5lxjjqkaagw2pyqlq0a-tigerbeetle-0.16.12",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/6lnwnr3mvdamm5lxjjqkaagw2pyqlq0a-tigerbeetle-0.16.12"
|
|
||||||
},
|
|
||||||
"x86_64-linux": {
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "out",
|
|
||||||
"path": "/nix/store/afrj2ph61xz0lh7f3d1g1d7v2rslbvny-tigerbeetle-0.16.12",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"store_path": "/nix/store/afrj2ph61xz0lh7f3d1g1d7v2rslbvny-tigerbeetle-0.16.12"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
version: "0.6"
|
|
||||||
|
|
||||||
processes:
|
|
||||||
ipfs:
|
|
||||||
namespace: testnet
|
|
||||||
command: "devbox run ipfs"
|
|
||||||
background: true
|
|
||||||
availability:
|
|
||||||
restart: never
|
|
||||||
max_restarts: 0
|
|
||||||
|
|
||||||
sonr:
|
|
||||||
namespace: testnet
|
|
||||||
background: true
|
|
||||||
command: "devbox run sonr"
|
|
||||||
restart: never
|
|
||||||
max_restarts: 1
|
|
||||||
depends:
|
|
||||||
- ipfs
|
|
||||||
|
|
||||||
hway:
|
|
||||||
namespace: testnet
|
|
||||||
background: true
|
|
||||||
command: "devbox run hway"
|
|
||||||
restart: never
|
|
||||||
max_restarts: 1
|
|
||||||
depends:
|
|
||||||
- ipfs
|
|
||||||
- sonr
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
This file defines the database schema for the PostgresQL ("psql") event sink
|
|
||||||
implementation in CometBFT. The operator must create a database and install
|
|
||||||
this schema before using the database to index events.
|
|
||||||
*/
|
|
||||||
|
|
||||||
-- The blocks table records metadata about each block.
|
|
||||||
-- The block record does not include its events or transactions (see tx_results).
|
|
||||||
CREATE TABLE blocks (
|
|
||||||
rowid BIGSERIAL PRIMARY KEY,
|
|
||||||
|
|
||||||
height BIGINT NOT NULL,
|
|
||||||
chain_id VARCHAR NOT NULL,
|
|
||||||
|
|
||||||
-- When this block header was logged into the sink, in UTC.
|
|
||||||
created_at TIMESTAMPTZ NOT NULL,
|
|
||||||
|
|
||||||
UNIQUE (height, chain_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Index blocks by height and chain, since we need to resolve block IDs when
|
|
||||||
-- indexing transaction records and transaction events.
|
|
||||||
CREATE INDEX idx_blocks_height_chain ON blocks(height, chain_id);
|
|
||||||
|
|
||||||
-- The tx_results table records metadata about transaction results. Note that
|
|
||||||
-- the events from a transaction are stored separately.
|
|
||||||
CREATE TABLE tx_results (
|
|
||||||
rowid BIGSERIAL PRIMARY KEY,
|
|
||||||
|
|
||||||
-- The block to which this transaction belongs.
|
|
||||||
block_id BIGINT NOT NULL REFERENCES blocks(rowid),
|
|
||||||
-- The sequential index of the transaction within the block.
|
|
||||||
index INTEGER NOT NULL,
|
|
||||||
-- When this result record was logged into the sink, in UTC.
|
|
||||||
created_at TIMESTAMPTZ NOT NULL,
|
|
||||||
-- The hex-encoded hash of the transaction.
|
|
||||||
tx_hash VARCHAR NOT NULL,
|
|
||||||
-- The protobuf wire encoding of the TxResult message.
|
|
||||||
tx_result BYTEA NOT NULL,
|
|
||||||
|
|
||||||
UNIQUE (block_id, index)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- The events table records events. All events (both block and transaction) are
|
|
||||||
-- associated with a block ID; transaction events also have a transaction ID.
|
|
||||||
CREATE TABLE events (
|
|
||||||
rowid BIGSERIAL PRIMARY KEY,
|
|
||||||
|
|
||||||
-- The block and transaction this event belongs to.
|
|
||||||
-- If tx_id is NULL, this is a block event.
|
|
||||||
block_id BIGINT NOT NULL REFERENCES blocks(rowid),
|
|
||||||
tx_id BIGINT NULL REFERENCES tx_results(rowid),
|
|
||||||
|
|
||||||
-- The application-defined type label for the event.
|
|
||||||
type VARCHAR NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
-- The attributes table records event attributes.
|
|
||||||
CREATE TABLE attributes (
|
|
||||||
event_id BIGINT NOT NULL REFERENCES events(rowid),
|
|
||||||
key VARCHAR NOT NULL, -- bare key
|
|
||||||
composite_key VARCHAR NOT NULL, -- composed type.key
|
|
||||||
value VARCHAR NULL,
|
|
||||||
|
|
||||||
UNIQUE (event_id, key)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- A joined view of events and their attributes. Events that do not have any
|
|
||||||
-- attributes are represented as a single row with empty key and value fields.
|
|
||||||
CREATE VIEW event_attributes AS
|
|
||||||
SELECT block_id, tx_id, type, key, composite_key, value
|
|
||||||
FROM events LEFT JOIN attributes ON (events.rowid = attributes.event_id);
|
|
||||||
|
|
||||||
-- A joined view of all block events (those having tx_id NULL).
|
|
||||||
CREATE VIEW block_events AS
|
|
||||||
SELECT blocks.rowid as block_id, height, chain_id, type, key, composite_key, value
|
|
||||||
FROM blocks JOIN event_attributes ON (blocks.rowid = event_attributes.block_id)
|
|
||||||
WHERE event_attributes.tx_id IS NULL;
|
|
||||||
|
|
||||||
-- A joined view of all transaction events.
|
|
||||||
CREATE VIEW tx_events AS
|
|
||||||
SELECT height, index, chain_id, type, key, composite_key, value, tx_results.created_at
|
|
||||||
FROM blocks JOIN tx_results ON (blocks.rowid = tx_results.block_id)
|
|
||||||
JOIN event_attributes ON (tx_results.rowid = event_attributes.tx_id)
|
|
||||||
WHERE event_attributes.tx_id IS NOT NULL;
|
|
||||||
-44
@@ -1,44 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json",
|
|
||||||
"packages": [
|
|
||||||
"go@1.22",
|
|
||||||
"bun@latest",
|
|
||||||
"gum@latest",
|
|
||||||
"ipfs@latest",
|
|
||||||
"skate@latest",
|
|
||||||
"air@latest",
|
|
||||||
"go-task@latest",
|
|
||||||
"templ@latest",
|
|
||||||
"tigerbeetle@latest",
|
|
||||||
"process-compose@latest"
|
|
||||||
],
|
|
||||||
"env": {
|
|
||||||
"GOPATH": "$HOME/go",
|
|
||||||
"PATH": "./build:$HOME/go/bin:$PATH",
|
|
||||||
"CHAIN_ID": "sonr-testnet-1",
|
|
||||||
"DENOM": "usnr",
|
|
||||||
"KEYRING": "test",
|
|
||||||
"MONIKER": "florence",
|
|
||||||
"BINARY": "sonrd",
|
|
||||||
"ACC0_NAME": "acc0",
|
|
||||||
"ACC1_NAME": "acc1",
|
|
||||||
"ACC0_ADDRESS": "idx1efd63aw40lxf3n4mhf7dzhjkr453axur9vjt6y",
|
|
||||||
"ACC1_ADDRESS": "idx1hj5fveer5cjtn4wd6wstzugjfdxzl0xpecp0nd",
|
|
||||||
"ACC0_MNEMONIC": "$(skate get ACC0_MNEMONIC)",
|
|
||||||
"ACC1_MNEMONIC": "$(skate get ACC1_MNEMONIC)",
|
|
||||||
"TUNNEL_TOKEN": "$(skate get CLOUDFLARE_TUNNEL_TOKEN)",
|
|
||||||
"TURNSTILE_SITE_KEY": "$(skate get TURNSTILE_SITE_KEY)",
|
|
||||||
"TEMPL_EXPERIMENT": "rawgo"
|
|
||||||
},
|
|
||||||
"shell": {
|
|
||||||
"scripts": {
|
|
||||||
"deploy": [
|
|
||||||
"gum spin --title='Generating PKL' -- make pkl-gen",
|
|
||||||
"gum spin --title='Building Motr WASM' -- make motr-build",
|
|
||||||
"gum spin --title='Uploading to Bucket' -- make deploy-cdn"
|
|
||||||
],
|
|
||||||
"devnet": ["process-compose up -f deploy/devnet/process-compose.yaml"],
|
|
||||||
"testnet": ["process-compose run -f deploy/testnet/process-compose.yaml"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user