Skip to content

Commit

Permalink
Added support for vaults locked until a specific time.
Browse files Browse the repository at this point in the history
Although not exposed in the UI, the Vault contract allows users to lock their vault for a time period (unlock 'until' time X).
  • Loading branch information
pbennett committed Jan 9, 2024
1 parent add2148 commit cf2a772
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 9 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,16 @@ Some of the supported properties are:
* ALGORAND_DATA
* If specified, tries to load node configuration data from the algod.net / algod.token file in this dir.
* ALGO_NFD_URL
* The https:// address of the NFD API (defaulted for you for each -network)
* The https:// address of the NFD API (defaulted for you - for each network)
* ALGO_ALGOD_URL / ALGO_ALGOD_TOKEN
* URL to algod endpoint and token (if needed) - defaults to algonode
* ALGO_ALGOD_HEADERS
* Rarely needed - but allows header:value,header:value pairs - adds to headers passed to algod node requests.

## Results

It's simple but currently the results of each send are appended to success.txt and failure.txt files in the current directory.
It's simple but currently the results of each send are appended to success.txt and failure.txt files in the current directory.
The failure count will be reported at the end. If any fail, you should check the failures reported and possibly send manually.

---
### Note on use of NFD Api
Expand Down
38 changes: 31 additions & 7 deletions nfd-helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,30 @@ func IsContractVersionAtLeast(version string, major, minor int) bool {
return false
}

// IsVaultAutoOptInLockedForSender returns true if the specified 'sender' address
// would be allowed to send to the NFDs vault. This is basically an off-chain
// validation of what the contract itself will do, to save some trouble and skip sending to a vault that won't
// allow it.
// "0" or missing unlocked, "1" explicitly locked, >1 a timestamp specifying unlocked 'until' specified timestamp
func IsVaultAutoOptInLockedForSender(n *nfdapi.NfdRecord, sender string) bool {
lockedVal, ok := n.Properties.Internal["vaultOptInLocked"]
if !ok {
// not found - defaults to UNLOCKED
return false
}
// explicitly unlocked or unlocked until time X (larger number)
intVal, _ := strconv.ParseUint(lockedVal, 10, 64)
if lockedVal == "0" {
return false
} else if intVal > 1 {
if time.Unix(int64(intVal), 0).After(time.Now().UTC()) {
return false
}
}
// Locked explicitly - or implicitly (because expired) - so only owner will return false (unlocked)
return sender != n.Owner
}

func retryNfdApiCalls(meth func() error) error {
return repeat.Repeat(
repeat.Fn(func() error {
Expand All @@ -66,7 +90,7 @@ func retryNfdApiCalls(meth func() error) error {
func getAllNfds(onlyRoots bool, requireVaults bool) ([]*nfdapi.NfdRecord, error) {
var (
offset, limit int32 = 0, 200
records nfdapi.NfdV2SearchRecords
fetchedNfds nfdapi.NfdV2SearchRecords
err error
nfds []*nfdapi.NfdRecord
)
Expand All @@ -82,29 +106,29 @@ func getAllNfds(onlyRoots bool, requireVaults bool) ([]*nfdapi.NfdRecord, error)
if onlyRoots {
searchOpts.Traits = optional.NewInterface("pristine")
}
records, _, err = api.NfdApi.NfdSearchV2(ctx, searchOpts)
fetchedNfds, _, err = api.NfdApi.NfdSearchV2(ctx, searchOpts)
return err
})

if err != nil {
return nil, fmt.Errorf("error while fetching segments: %w", err)
}

if records.Nfds == nil || len(*records.Nfds) == 0 {
if fetchedNfds.Nfds == nil || len(*fetchedNfds.Nfds) == 0 {
break
}
for _, record := range *records.Nfds {
if record.DepositAccount == "" {
for _, nfd := range *fetchedNfds.Nfds {
if nfd.DepositAccount == "" {
continue
}
if requireVaults {
// contract has to be at least 2.11 and not be locked for vault receipt
if !IsContractVersionAtLeast(record.Properties.Internal["ver"], 2, 11) || record.Properties.Internal["vaultOptInLocked"] == "1" {
if !IsContractVersionAtLeast(nfd.Properties.Internal["ver"], 2, 11) || IsVaultAutoOptInLockedForSender(&nfd, types.ZeroAddress.String()) {
continue
}
}

newRecord := record
newRecord := nfd
nfds = append(nfds, &newRecord)
}
}
Expand Down

0 comments on commit cf2a772

Please sign in to comment.