-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
09d70eb
commit d808d82
Showing
6 changed files
with
305 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import "StringUtils" | ||
|
||
pub contract AddressUtils { | ||
|
||
pub fun withoutPrefix(_ input: String): String { | ||
var address = input | ||
|
||
// get rid of 0x | ||
if address.length > 1 && address.utf8[1] == 120 { | ||
address = address.slice(from: 2, upTo: address.length) | ||
} | ||
|
||
// ensure even length | ||
if address.length % 2 == 1 { | ||
address = "0".concat(address) | ||
} | ||
return address | ||
} | ||
|
||
pub fun parseUInt64(_ input: AnyStruct): UInt64? { | ||
var stringValue = "" | ||
|
||
if let string = input as? String { | ||
stringValue = string | ||
} else if let address = input as? Address { | ||
stringValue = address.toString() | ||
} else if let type = input as? Type { | ||
let parts = StringUtils.split(type.identifier, ".") | ||
if parts.length == 1 { | ||
return nil | ||
} | ||
stringValue = parts[1] | ||
} else { | ||
return nil | ||
} | ||
|
||
let address = self.withoutPrefix(stringValue) | ||
let bytes = address.decodeHex() | ||
var r: UInt64 = 0 | ||
var length = bytes.length | ||
for byte in bytes { | ||
length = length - 1 | ||
r = r + (UInt64(byte) << UInt64(length * 8)) | ||
} | ||
return r | ||
} | ||
|
||
pub fun parseAddress(_ input: AnyStruct): Address? { | ||
if let parsed = self.parseUInt64(input) { | ||
return Address(parsed) | ||
} | ||
return nil | ||
} | ||
|
||
pub fun isValidAddress(_ input: AnyStruct, forNetwork: String): Bool { | ||
let address = self.parseUInt64(input) | ||
if address == nil { | ||
return false | ||
} | ||
|
||
let codeWords: {String: UInt64} = { | ||
"MAINNET" : 0, | ||
"TESTNET" : 0x6834ba37b3980209, | ||
"EMULATOR": 0x1cb159857af02018 | ||
} | ||
|
||
let parityCheckMatrixColumns: [UInt64] = [ | ||
0x00001, 0x00002, 0x00004, 0x00008, 0x00010, 0x00020, 0x00040, 0x00080, | ||
0x00100, 0x00200, 0x00400, 0x00800, 0x01000, 0x02000, 0x04000, 0x08000, | ||
0x10000, 0x20000, 0x40000, 0x7328d, 0x6689a, 0x6112f, 0x6084b, 0x433fd, | ||
0x42aab, 0x41951, 0x233ce, 0x22a81, 0x21948, 0x1ef60, 0x1deca, 0x1c639, | ||
0x1bdd8, 0x1a535, 0x194ac, 0x18c46, 0x1632b, 0x1529b, 0x14a43, 0x13184, | ||
0x12942, 0x118c1, 0x0f812, 0x0e027, 0x0d00e, 0x0c83c, 0x0b01d, 0x0a831, | ||
0x0982b, 0x07034, 0x0682a, 0x05819, 0x03807, 0x007d2, 0x00727, 0x0068e, | ||
0x0067c, 0x0059d, 0x004eb, 0x003b4, 0x0036a, 0x002d9, 0x001c7, 0x0003f | ||
] | ||
|
||
var parity: UInt64 = 0 | ||
var codeWord: UInt64 = codeWords[forNetwork]! | ||
codeWord = codeWord ^ address! | ||
|
||
if codeWord == 0 { | ||
return false | ||
} | ||
|
||
for column in parityCheckMatrixColumns{ | ||
if codeWord & 1 == 1 { | ||
parity = parity ^ column | ||
} | ||
codeWord = codeWord >> 1 | ||
} | ||
|
||
return parity == 0 && codeWord == 0 | ||
} | ||
|
||
pub fun getNetworkFromAddress(_ input: AnyStruct): String? { | ||
for network in ["MAINNET", "TESTNET", "EMULATOR"]{ | ||
if self.isValidAddress(input, forNetwork: network){ | ||
return network | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
pub fun currentNetwork(): String { | ||
return self.getNetworkFromAddress(self.account.address)! | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copied from https://github.com/bluesign/flow-utils/blob/dnz/cadence/contracts/ArrayUtils.cdc with minor adjustments | ||
pub contract ArrayUtils { | ||
|
||
pub fun rangeFunc(_ start: Int, _ end: Int, _ f: ((Int): Void)) { | ||
var current = start | ||
while current < end { | ||
f(current) | ||
current = current + 1 | ||
} | ||
} | ||
|
||
pub fun range(_ start: Int, _ end: Int): [Int] { | ||
var res: [Int] = [] | ||
self.rangeFunc(start, end, fun (i: Int) { | ||
res.append(i) | ||
}) | ||
return res | ||
} | ||
|
||
pub fun reverse(_ array: [Int]): [Int] { | ||
var res: [Int] = [] | ||
var i: Int = array.length - 1 | ||
while i >= 0 { | ||
res.append(array[i]) | ||
i = i - 1 | ||
} | ||
return res | ||
} | ||
|
||
pub fun transform(_ array: &[AnyStruct], _ f : ((AnyStruct): AnyStruct)){ | ||
for i in self.range(0, array.length){ | ||
array[i] = f(array[i]) | ||
} | ||
} | ||
|
||
pub fun iterate(_ array: [AnyStruct], _ f : ((AnyStruct): Bool)){ | ||
for item in array{ | ||
if !f(item){ | ||
break | ||
} | ||
} | ||
} | ||
|
||
pub fun map(_ array: [AnyStruct], _ f : ((AnyStruct): AnyStruct)) : [AnyStruct] { | ||
var res : [AnyStruct] = [] | ||
for item in array{ | ||
res.append(f(item)) | ||
} | ||
return res | ||
} | ||
|
||
pub fun mapStrings(_ array: [String], _ f: ((String) : String) ) : [String] { | ||
var res : [String] = [] | ||
for item in array{ | ||
res.append(f(item)) | ||
} | ||
return res | ||
} | ||
|
||
pub fun reduce(_ array: [AnyStruct], _ initial: AnyStruct, _ f : ((AnyStruct, AnyStruct): AnyStruct)) : AnyStruct{ | ||
var res: AnyStruct = f(initial, array[0]) | ||
for i in self.range(1, array.length){ | ||
res = f(res, array[i]) | ||
} | ||
return res | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import "ArrayUtils" | ||
|
||
pub contract StringUtils { | ||
|
||
pub fun format(_ s: String, _ args: {String:String}): String{ | ||
var formatted = s | ||
for key in args.keys{ | ||
formatted = StringUtils.replaceAll(formatted, "{".concat(key).concat("}"), args[key]!) | ||
} | ||
return formatted | ||
} | ||
|
||
pub fun explode(_ s: String): [String]{ | ||
var chars : [String] = [] | ||
for i in ArrayUtils.range(0, s.length){ | ||
chars.append(s[i].toString()) | ||
} | ||
return chars | ||
} | ||
|
||
pub fun trimLeft(_ s: String): String{ | ||
for i in ArrayUtils.range(0, s.length){ | ||
if s[i] != " "{ | ||
return s.slice(from: i, upTo: s.length) | ||
} | ||
} | ||
return "" | ||
} | ||
|
||
pub fun trim(_ s: String): String{ | ||
return self.trimLeft(s) | ||
} | ||
|
||
pub fun replaceAll(_ s: String, _ search: String, _ replace: String): String{ | ||
return self.join(self.split(s, search), replace) | ||
} | ||
|
||
pub fun hasPrefix(_ s: String, _ prefix: String) : Bool{ | ||
return s.length >= prefix.length && s.slice(from:0, upTo: prefix.length)==prefix | ||
} | ||
|
||
pub fun hasSuffix(_ s: String, _ suffix: String) : Bool{ | ||
return s.length >= suffix.length && s.slice(from:s.length-suffix.length, upTo: s.length)==suffix | ||
} | ||
|
||
pub fun index(_ s : String, _ substr : String, _ startIndex: Int): Int?{ | ||
for i in ArrayUtils.range(startIndex,s.length-substr.length+1){ | ||
if s[i]==substr[0] && s.slice(from:i, upTo:i+substr.length) == substr{ | ||
return i | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
pub fun count(_ s: String, _ substr: String): Int{ | ||
var pos = [self.index(s, substr, 0)] | ||
while pos[0]!=nil { | ||
pos.insert(at:0, self.index(s, substr, pos[0]!+pos.length*substr.length+1)) | ||
} | ||
return pos.length-1 | ||
} | ||
|
||
pub fun contains(_ s: String, _ substr: String): Bool { | ||
if let index = self.index(s, substr, 0) { | ||
return true | ||
} | ||
return false | ||
} | ||
|
||
pub fun substringUntil(_ s: String, _ until: String, _ startIndex: Int): String{ | ||
if let index = self.index( s, until, startIndex){ | ||
return s.slice(from:startIndex, upTo: index) | ||
} | ||
return s.slice(from:startIndex, upTo:s.length) | ||
} | ||
|
||
pub fun split(_ s: String, _ delimiter: String): [String] { | ||
let segments: [String] = [] | ||
var p = 0 | ||
while p<=s.length{ | ||
var preDelimiter = self.substringUntil(s, delimiter, p) | ||
segments.append(preDelimiter) | ||
p = p + preDelimiter.length + delimiter.length | ||
} | ||
return segments | ||
} | ||
|
||
pub fun join(_ strs: [String], _ separator: String): String { | ||
var joinedStr = "" | ||
for s in strs { | ||
joinedStr = joinedStr.concat(s).concat(separator) | ||
} | ||
return joinedStr.slice(from: 0, upTo: joinedStr.length - separator.length) | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters