@@ -18,29 +18,53 @@ access(all) contract TidalYieldClosedBeta {
1818 access (all ) event BetaGranted (addr : Address , capID : UInt64 )
1919 access (all ) event BetaRevoked (addr : Address , capID : UInt64 ? )
2020
21+ /// Per-user badge storage path (under the *contract/deployer* account)
22+ access (contract ) fun _badgePath (_ addr : Address ): StoragePath {
23+ return StoragePath (identifier : " TY_BetaBadge_" .concat (addr .toString ()))!
24+ }
25+
26+ /// Ensure the admin-owned badge exists for the user
27+ access (contract ) fun _ensureBadge (_ addr : Address ) {
28+ let p = self ._badgePath (addr )
29+ if self .account .storage .type (at : p ) == nil {
30+ self .account .storage .save (<- create BetaBadge (), to : p )
31+ }
32+ }
33+
34+ /// Issue a capability from the contract/deployer account and record its ID
35+ access (contract ) fun _issueBadgeCap (_ addr : Address ): Capability <&{TidalYieldClosedBeta .IBeta }> {
36+ let p = self ._badgePath (addr )
37+ let cap : Capability <&{TidalYieldClosedBeta .IBeta }> =
38+ self .account .capabilities .storage .issue <&{TidalYieldClosedBeta .IBeta }>(p )
39+ self .issuedCapIDs [addr ] = cap .id
40+
41+ if let ctrl = self .account .capabilities .storage .getController (byCapabilityID : cap .id ) {
42+ ctrl .setTag (" tidalyield-beta" )
43+ }
44+
45+ emit BetaGranted (addr : addr , capID : cap .id )
46+ return cap
47+ }
48+
49+ /// Delete the recorded controller, revoking *all copies* of the capability
50+ access (contract ) fun _revokeByAddress (_ addr : Address ) {
51+ let id = self .issuedCapIDs [addr ] ?? panic (" No cap recorded for address" )
52+ let ctrl = self .account .capabilities .storage .getController (byCapabilityID : id )
53+ ?? panic (" Missing controller for recorded cap ID" )
54+ ctrl .delete ()
55+ self .issuedCapIDs .remove (key : addr )
56+ emit BetaRevoked (addr : addr , capID : id )
57+ }
58+
2159 // 2) A small in-account helper resource that performs privileged ops
2260 access (all ) resource AdminHandle {
23- access (Admin ) fun grantBeta (addr : Address ): Capability <&{TidalYieldClosedBeta .BetaBadge }> {
24- // Store a badge under a path derived from the user address, but in ADMIN storage
25- let path = StoragePath (identifier : " TY_BetaBadge_" .concat (addr .toString ()))!
26- // create only once
27- if self .account .storage .type (at : path ) == nil {
28- self .account .storage .save (<- create TidalYieldClosedBeta .BetaBadge (addr ), to : path )
29- }
30- // Issue a capability FROM ADMIN (controller in admin)
31- let cap : Capability <&{TidalYieldClosedBeta .BetaBadge }> =
32- self .account .capabilities .storage .issue <&{TidalYieldClosedBeta .BetaBadge }>(path )
33- TidalYieldClosedBeta .issuedCapIDs [addr ] = cap .id
34-
35- return cap
61+ access (Admin ) fun grantBeta (addr : Address ): Capability <&{TidalYieldClosedBeta .IBeta }> {
62+ TidalYieldClosedBeta ._ensureBadge (addr )
63+ return TidalYieldClosedBeta ._issueBadgeCap (addr )
3664 }
3765
3866 access (Admin ) fun revokeByAddress (addr : Address ) {
39- let id = TidalYieldClosedBeta .issuedCapIDs [addr ] ?? panic (" No cap recorded" )
40- let ctrl = self .account .capabilities .storage .getController (byCapabilityID : id )
41- ?? panic (" Missing controller" )
42- ctrl .delete ()
43- TidalYieldClosedBeta .issuedCapIDs .remove (key : addr )
67+ TidalYieldClosedBeta ._revokeByAddress (addr )
4468 }
4569 }
4670
0 commit comments