-
Notifications
You must be signed in to change notification settings - Fork 7
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
767623c
commit 0b4298d
Showing
1 changed file
with
49 additions
and
18 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 |
---|---|---|
@@ -1,31 +1,62 @@ | ||
import "EVM" | ||
import "Burner" | ||
import "FungibleToken" | ||
import "FlowToken" | ||
import "EVM" | ||
|
||
/// Creates a COA and saves it in the signer's Flow account & passing the given value of Flow into FlowEVM | ||
/// | ||
transaction(amount: UFix64) { | ||
let sentVault: @FlowToken.Vault | ||
let auth: auth(IssueStorageCapabilityController, IssueStorageCapabilityController, PublishCapability, SaveValue, UnpublishCapability) &Account | ||
let fundingVault: @FlowToken.Vault? | ||
let coa: &EVM.CadenceOwnedAccount | ||
|
||
prepare(signer: auth(BorrowValue, SaveValue, IssueStorageCapabilityController, PublishCapability) &Account) { | ||
/* --- Configure COA --- */ | ||
// | ||
// Ensure there is not yet a CadenceOwnedAccount in the standard path | ||
let coaPath = /storage/evm | ||
if signer.storage.type(at: coaPath) != nil { | ||
panic( | ||
"Object already exists in signer's account at path=".concat(coaPath.toString()) | ||
.concat(". Make sure the signing account does not already have a CadenceOwnedAccount.") | ||
) | ||
} | ||
// COA not found in standard path, create and publish a public **unentitled** capability | ||
signer.storage.save(<-EVM.createCadenceOwnedAccount(), to: coaPath) | ||
let coaCapability = signer.capabilities.storage.issue<&EVM.CadenceOwnedAccount>(coaPath) | ||
signer.capabilities.publish(coaCapability, at: /public/evm) | ||
|
||
prepare(signer: auth(BorrowValue, IssueStorageCapabilityController, PublishCapability, SaveValue, UnpublishCapability) &Account) { | ||
let vaultRef = signer.storage.borrow<auth(FungibleToken.Withdraw) &FlowToken.Vault>( | ||
from: /storage/flowTokenVault | ||
) ?? panic("Could not borrow reference to the owner's Vault!") | ||
// Borrow the CadenceOwnedAccount reference | ||
self.coa = signer.storage.borrow<&EVM.CadenceOwnedAccount>( | ||
from: coaPath | ||
) ?? panic( | ||
"Could not find CadenceOwnedAccount (COA) in signer's account at path=".concat(coaPath.toString()) | ||
.concat(". Make sure the signing account has initialized a COA at the expected path.") | ||
) | ||
|
||
self.sentVault <- vaultRef.withdraw(amount: amount) as! @FlowToken.Vault | ||
self.auth = signer | ||
/* --- Assign fundingVault --- */ | ||
// | ||
if amount > 0.0 { | ||
// Reference the signer's FLOW vault & withdraw the funding amount | ||
let vault = signer.storage.borrow<auth(FungibleToken.Withdraw) &FlowToken.Vault>(from: /storage/flowTokenVault) | ||
?? panic("Could not borrow a reference to the signer's FLOW vault from path=/storage/flowTokenVault") | ||
self.fundingVault <- vault.withdraw(amount: amount) as! @FlowToken.Vault | ||
} else { | ||
// No funding requested, so no need to withdraw from the vault | ||
self.fundingVault <- nil | ||
} | ||
} | ||
|
||
execute { | ||
let coa <- EVM.createCadenceOwnedAccount() | ||
coa.deposit(from: <-self.sentVault) | ||
pre { | ||
self.fundingVault == nil || self.fundingVault?.balance ?? 0.0 == amount: | ||
"Mismatched funding vault acquired given requested amount=".concat(amount.toString()) | ||
} | ||
|
||
let storagePath = StoragePath(identifier: "evm")! | ||
let publicPath = PublicPath(identifier: "evm")! | ||
self.auth.storage.save<@EVM.CadenceOwnedAccount>(<-coa, to: storagePath) | ||
let addressableCap = self.auth.capabilities.storage.issue<&EVM.CadenceOwnedAccount>(storagePath) | ||
self.auth.capabilities.unpublish(publicPath) | ||
self.auth.capabilities.publish(addressableCap, at: publicPath) | ||
execute { | ||
// Fund if necessary | ||
if self.fundingVault != nil || self.fundingVault?.balance ?? 0.0 > 0.0 { | ||
self.coa.deposit(from: <-self.fundingVault!) | ||
} else { | ||
Burner.burn(<-self.fundingVault) | ||
} | ||
} | ||
} |