-
Notifications
You must be signed in to change notification settings - Fork 440
feat(examples): add subscriptions package #4931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
feat(examples): add subscriptions package #4931
Conversation
🛠 PR Checks Summary🔴 Pending initial approval by a review team member, or review from tech-staff Manual Checks (for Reviewers):
Read More🤖 This bot helps streamline PR reviews by verifying automated checks and providing guidance for contributors and reviewers. ✅ Automated Checks (for Contributors):🟢 Maintainers must be able to edit this pull request (more info) ☑️ Contributor Actions:
☑️ Reviewer Actions:
📚 Resources:Debug
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should:
- Add a README for explaining what the realm is about + main public function
- Add a dashboard in the UI to explain how to use the service (Exemple: add subscription)
(I can do a PR for this additions) - You should add events for important operation
- There's some inconsistency, when sometime you use
panic(...)and sometimespanic(errors.New(...))
| // XXX: this part is 100% from payrolls realm from N0izN0iz <3 | ||
| // Payrolls realm: https://github.com/gnolang/gno/pull/3432 | ||
|
|
||
| // Coins transforms coins into subscriptions coins, prefixing their denom them with their type. Examples: "ugnot" -> "/native/ugnot", "gno.land/r/demo/foo20" -> "/grc20/gno.land/r/demo/foo20" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be move to its own standalone package
/p/samcrew/coins/normalizedCoins.gno
Or something like that
|
|
||
| func sendCoins(dst address, coins chain.Coins) { | ||
| if len(coins) == 0 { | ||
| return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of returning silently, we should return an error, a status or a panic
| return "" | ||
| } | ||
|
|
||
| func humanDuration(d time.Duration) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be moved to its own package. This may be useful in other situations.
Maybe we can create /p/samcrew/renderutils, and add more later on.
| out[j].Amount = coin.Amount | ||
| out[j].Denom = "/grc20/" + coin.Denom | ||
| } | ||
| return out, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error is always == to nil
If both len == 0, we should return an error
| // Payrolls realm: https://github.com/gnolang/gno/pull/3432 | ||
|
|
||
| // Coins transforms coins into subscriptions coins, prefixing their denom them with their type. Examples: "ugnot" -> "/native/ugnot", "gno.land/r/demo/foo20" -> "/grc20/gno.land/r/demo/foo20" | ||
| func Coins(cur realm, native chain.Coins, grc20 chain.Coins) (chain.Coins, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| func Coins(cur realm, native chain.Coins, grc20 chain.Coins) (chain.Coins, error) { | |
| func PrefixCoins(cur realm, native chain.Coins, grc20 chain.Coins) (chain.Coins, error) { |
Or NormalizeCoins, FormatCoins
| // - serviceName: the name of the service to subscribe to | ||
| // - fqName: the fully qualified name of the GRC20 token to use for payment (empty string for native coins) | ||
| // - amount: the amount of GRC20 tokens to deposit initially (0 for native coins) | ||
| func Subscribe(cur realm, serviceName string, fqName string, amount int64) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amount can be negative, even if it's verified after through coinsHasPositive, I think it is better to verify beforehand explicitly
| natSend := banker.OriginSend() | ||
| grc20Send := chain.Coins{} | ||
| if amount != 0 { | ||
| grc20Send = chain.NewCoins(chain.NewCoin("/grc20/"+fqName, amount)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
grc20send token are never actually transferred
// - amount: the amount of GRC20 tokens to deposit initially (0 for native coins)
|
|
||
| // ServiceClaimVault allows the owner of a service to claim the funds in the service's vault | ||
| // - displayName: the name of the service | ||
| func ServiceClaimVault(cur realm, displayName string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not update lastChargedAt
| // Topup allows a user to top up their subscription balance using native coins or GRC20 tokens | ||
| // - serviceName: the name of the service to top up | ||
| // - fqName: the fully qualified name of the GRC20 token to use for top up (empty string for native coins) | ||
| // - amount: the amount of GRC20 tokens to deposit (0 for native coins) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment should be change, as it is possible to topup native and grc20 in one tx
| sub := subValue.(*subscription) | ||
| due, _ := sub.dueAmount(svc.renewalPeriod, svc.price) | ||
| if coinsHasPositive(due) { | ||
| sendCoins(svc.owner.Owner(), due) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't update lastChargedAt
a package that handle subscriptions either with native coins or grc20 coins.
a public API with a way to create service where users can subscribe and top up their account.
Services owners can check the status of a user subscription to give access or not to a service.
The coins part is from payrolls realm available here: #3432
I added unit test for the coins handling part that is the most "critical" one.