-
Notifications
You must be signed in to change notification settings - Fork 20
/
templates.go
163 lines (137 loc) · 4.51 KB
/
templates.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package overflow
import (
"encoding/base64"
"fmt"
)
// Templates
//
// A list of functions you can use to perform some common operations
// UploadFile reads a file, base64 encodes it and chunk upload to /storage/upload
func (o *OverflowState) UploadFile(filename string, accountName string) error {
content, err := fileAsBase64(filename)
if err != nil {
return err
}
return o.UploadString(content, accountName)
}
// DownloadAndUploadFile reads a file, base64 encodes it and chunk upload to /storage/upload
func (o *OverflowState) DownloadAndUploadFile(url string, accountName string) error {
body, err := getUrl(url)
if err != nil {
return err
}
encoded := base64.StdEncoding.EncodeToString(body)
return o.UploadString(encoded, accountName)
}
// DownloadImageAndUploadAsDataUrl download an image and upload as data url
func (o *OverflowState) DownloadImageAndUploadAsDataUrl(url, accountName string) error {
body, err := getUrl(url)
if err != nil {
return err
}
content := contentAsImageDataUrl(body)
return o.UploadString(content, accountName)
}
// UploadImageAsDataUrl will upload a image file from the filesystem into /storage/upload of the given account
func (o *OverflowState) UploadImageAsDataUrl(filename string, accountName string) error {
content, err := fileAsImageData(filename)
if err != nil {
return err
}
return o.UploadString(content, accountName)
}
// UploadString will upload the given string data in 1mb chunkts to /storage/upload of the given account
func (o *OverflowState) UploadString(content string, accountName string) error {
// unload previous content if any.
res := o.Tx(`
transaction {
prepare(signer: auth(LoadValue) &Account) {
let path = /storage/upload
let existing = signer.storage.load<String>(from: path) ?? ""
log(existing)
}
}
`, WithSigner(accountName))
if res.Err != nil {
return res.Err
}
parts := splitByWidthMake(content, 1_000_000)
for _, part := range parts {
res := o.Tx(`
transaction(part: String) {
prepare(signer: auth(Storage) &Account) {
let path = /storage/upload
let existing = signer.storage.load<String>(from: path) ?? ""
signer.storage.save(existing.concat(part), to: path)
log(signer.address.toString())
log(part)
}
}
`, WithSigner(accountName), WithArg("part", part))
if res.Err != nil {
return res.Err
}
}
return nil
}
// Get the free capacity in an account
func (o *OverflowState) GetFreeCapacity(accountName string) int {
result := o.Script(`
access(all) fun main(user:Address): UInt64{
let account=getAccount(user)
return account.storage.capacity- account.storage.used
}
`, WithArg("user", accountName))
value, ok := result.Output.(uint64)
if !ok {
panic("Type conversion of free capacity failed")
}
return int(value)
}
func (o *OverflowState) MintFlowTokens(accountName string, amount float64) *OverflowState {
if o.Network.Name != "emulator" {
o.Error = fmt.Errorf("can only mint new flow on emulator")
return o
}
result := o.Tx(`
import FungibleToken from 0xee82856bf20e2aa6
import FlowToken from 0x0ae53cb6e3f42a79
transaction(recipient: Address, amount: UFix64) {
let tokenAdmin: &FlowToken.Administrator
let tokenReceiver: &{FungibleToken.Receiver}
prepare(signer: auth(BorrowValue) &Account) {
self.tokenAdmin = signer.storage
.borrow<&FlowToken.Administrator>(from: /storage/flowTokenAdmin)
?? panic("Signer is not the token admin")
self.tokenReceiver = getAccount(recipient).capabilities.borrow<&{FungibleToken.Receiver}>(/public/flowTokenReceiver)
?? panic("Unable to borrow receiver reference")
}
execute {
let minter <- self.tokenAdmin.createNewMinter(allowedAmount: amount)
let mintedVault <- minter.mintTokens(amount: amount)
self.tokenReceiver.deposit(from: <-mintedVault)
destroy minter
}
}
`, WithSignerServiceAccount(),
WithArg("recipient", accountName),
WithArg("amount", amount),
WithName(fmt.Sprintf("Startup Mint tokens for %s", accountName)),
WithoutLog(),
)
if result.Err != nil {
o.Error = result.Err
}
return o
}
// A method to fill up a users storage, useful when testing
// This has some issues with transaction fees
func (o *OverflowState) FillUpStorage(accountName string) *OverflowState {
capacity := o.GetFreeCapacity(accountName)
length := capacity - 50500 // we cannot fill up all of storage since we need flow to pay for the transaction that fills it up
err := o.UploadString(randomString(length), accountName)
if err != nil {
o.Error = err
}
return o
}