feat: Waku v2 bridge

Issue #12610
This commit is contained in:
Michal Iskierko
2023-11-12 13:29:38 +01:00
parent 56e7bd01ca
commit 6d31343205
6716 changed files with 1982502 additions and 5891 deletions

356
vendor/github.com/status-im/status-go/LICENSE.md generated vendored Normal file
View File

@@ -0,0 +1,356 @@
Mozilla Public License Version 2.0
==================================
### 1. Definitions
**1.1. “Contributor”**
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
**1.2. “Contributor Version”**
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
**1.3. “Contribution”**
means Covered Software of a particular Contributor.
**1.4. “Covered Software”**
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
**1.5. “Incompatible With Secondary Licenses”**
means
* **(a)** that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
* **(b)** that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
**1.6. “Executable Form”**
means any form of the work other than Source Code Form.
**1.7. “Larger Work”**
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
**1.8. “License”**
means this document.
**1.9. “Licensable”**
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
**1.10. “Modifications”**
means any of the following:
* **(a)** any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
* **(b)** any new file in Source Code Form that contains any Covered
Software.
**1.11. “Patent Claims” of a Contributor**
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
**1.12. “Secondary License”**
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
**1.13. “Source Code Form”**
means the form of the work preferred for making modifications.
**1.14. “You” (or “Your”)**
means an individual or a legal entity exercising rights under this
License. For legal entities, “You” includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, “control” means **(a)** the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or **(b)** ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
### 2. License Grants and Conditions
#### 2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
* **(a)** under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
* **(b)** under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
#### 2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
#### 2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
* **(a)** for any code that a Contributor has removed from Covered Software;
or
* **(b)** for infringements caused by: **(i)** Your and any other third party's
modifications of Covered Software, or **(ii)** the combination of its
Contributions with other software (except as part of its Contributor
Version); or
* **(c)** under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
#### 2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
#### 2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
#### 2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
#### 2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
### 3. Responsibilities
#### 3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
#### 3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
* **(a)** such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
* **(b)** You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
#### 3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
#### 3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
#### 3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
### 4. Inability to Comply Due to Statute or Regulation
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: **(a)** comply with
the terms of this License to the maximum extent possible; and **(b)**
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
### 5. Termination
**5.1.** The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated **(a)** provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and **(b)** on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
**5.2.** If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
**5.3.** In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
### 6. Disclaimer of Warranty
> Covered Software is provided under this License on an “as is”
> basis, without warranty of any kind, either expressed, implied, or
> statutory, including, without limitation, warranties that the
> Covered Software is free of defects, merchantable, fit for a
> particular purpose or non-infringing. The entire risk as to the
> quality and performance of the Covered Software is with You.
> Should any Covered Software prove defective in any respect, You
> (not any Contributor) assume the cost of any necessary servicing,
> repair, or correction. This disclaimer of warranty constitutes an
> essential part of this License. No use of any Covered Software is
> authorized under this License except under this disclaimer.
### 7. Limitation of Liability
> Under no circumstances and under no legal theory, whether tort
> (including negligence), contract, or otherwise, shall any
> Contributor, or anyone who distributes Covered Software as
> permitted above, be liable to You for any direct, indirect,
> special, incidental, or consequential damages of any character
> including, without limitation, damages for lost profits, loss of
> goodwill, work stoppage, computer failure or malfunction, or any
> and all other commercial damages or losses, even if such party
> shall have been informed of the possibility of such damages. This
> limitation of liability shall not apply to liability for death or
> personal injury resulting from such party's negligence to the
> extent applicable law prohibits such limitation. Some
> jurisdictions do not allow the exclusion or limitation of
> incidental or consequential damages, so this exclusion and
> limitation may not apply to You.
### 8. Litigation
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
### 9. Miscellaneous
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
### 10. Versions of the License
#### 10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
#### 10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
#### 10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
#### 10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
## Exhibit A - Source Code Form License Notice
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
## Exhibit B - “Incompatible With Secondary Licenses” Notice
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.

View File

@@ -0,0 +1,760 @@
package account
import (
"context"
"crypto/ecdsa"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"sync"
"time"
"github.com/google/uuid"
gethkeystore "github.com/ethereum/go-ethereum/accounts/keystore"
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/account/generator"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/keystore"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/extkeys"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/rpc"
)
// errors
var (
ErrAddressToAccountMappingFailure = errors.New("cannot retrieve a valid account for a given address")
ErrAccountToKeyMappingFailure = errors.New("cannot retrieve a valid key for a given account")
ErrNoAccountSelected = errors.New("no account has been selected, please login")
ErrInvalidMasterKeyCreated = errors.New("can not create master extended key")
ErrOnboardingNotStarted = errors.New("onboarding must be started before choosing an account")
ErrOnboardingAccountNotFound = errors.New("cannot find onboarding account with the given id")
ErrAccountKeyStoreMissing = errors.New("account key store is not set")
ErrInvalidPersonalSignAccount = errors.New("invalid account as only the selected one can generate a signature")
)
type ErrCannotLocateKeyFile struct {
Msg string
}
func (e ErrCannotLocateKeyFile) Error() string {
return e.Msg
}
var zeroAddress = types.Address{}
type SignParams struct {
Data interface{} `json:"data"`
Address string `json:"account"`
Password string `json:"password,omitempty"`
}
func (sp *SignParams) Validate(checkPassword bool) error {
if len(sp.Address) != 2*types.AddressLength+2 {
return errors.New("address has to be provided")
}
if sp.Data == "" {
return errors.New("data has to be provided")
}
if checkPassword && sp.Password == "" {
return errors.New("password has to be provided")
}
return nil
}
type RecoverParams struct {
Message string `json:"message"`
Signature string `json:"signature"`
}
// Manager represents account manager interface
type Manager interface {
GetVerifiedWalletAccount(db *accounts.Database, address, password string) (*SelectedExtKey, error)
Sign(rpcParams SignParams, verifiedAccount *SelectedExtKey) (result types.HexBytes, err error)
CanRecover(rpcParams RecoverParams, revealedAddress types.Address) (bool, error)
DeleteAccount(address types.Address) error
}
// DefaultManager represents default account manager implementation
type DefaultManager struct {
mu sync.RWMutex
rpcClient *rpc.Client
rpcTimeout time.Duration
Keydir string
keystore types.KeyStore
accountsGenerator *generator.Generator
onboarding *Onboarding
selectedChatAccount *SelectedExtKey // account that was processed during the last call to SelectAccount()
mainAccountAddress types.Address
watchAddresses []types.Address
}
// GetKeystore is only used in tests
func (m *DefaultManager) GetKeystore() types.KeyStore {
m.mu.RLock()
defer m.mu.RUnlock()
return m.keystore
}
// AccountsGenerator returns accountsGenerator.
func (m *DefaultManager) AccountsGenerator() *generator.Generator {
return m.accountsGenerator
}
// CreateAccount creates an internal geth account
// BIP44-compatible keys are generated: CKD#1 is stored as account key, CKD#2 stored as sub-account root
// Public key of CKD#1 is returned, with CKD#2 securely encoded into account key file (to be used for
// sub-account derivations)
func (m *DefaultManager) CreateAccount(password string) (generator.GeneratedAccountInfo, Info, string, error) {
var mkInfo generator.GeneratedAccountInfo
info := Info{}
// generate mnemonic phrase
mn := extkeys.NewMnemonic()
mnemonic, err := mn.MnemonicPhrase(extkeys.EntropyStrength128, extkeys.EnglishLanguage)
if err != nil {
return mkInfo, info, "", fmt.Errorf("can not create mnemonic seed: %v", err)
}
// Generate extended master key (see BIP32)
// We call extkeys.NewMaster with a seed generated with the 12 mnemonic words
// but without using the optional password as an extra entropy as described in BIP39.
// Future ideas/iterations in Status can add an an advanced options
// for expert users, to be able to add a passphrase to the generation of the seed.
extKey, err := extkeys.NewMaster(mn.MnemonicSeed(mnemonic, ""))
if err != nil {
return mkInfo, info, "", fmt.Errorf("can not create master extended key: %v", err)
}
acc := generator.NewAccount(nil, extKey)
mkInfo = acc.ToGeneratedAccountInfo("", mnemonic)
// import created key into account keystore
info.WalletAddress, info.WalletPubKey, err = m.importExtendedKey(extkeys.KeyPurposeWallet, extKey, password)
if err != nil {
return mkInfo, info, "", err
}
info.ChatAddress = info.WalletAddress
info.ChatPubKey = info.WalletPubKey
return mkInfo, info, mnemonic, nil
}
// RecoverAccount re-creates master key using given details.
// Once master key is re-generated, it is inserted into keystore (if not already there).
func (m *DefaultManager) RecoverAccount(password, mnemonic string) (Info, error) {
info := Info{}
// re-create extended key (see BIP32)
mn := extkeys.NewMnemonic()
extKey, err := extkeys.NewMaster(mn.MnemonicSeed(mnemonic, ""))
if err != nil {
return info, ErrInvalidMasterKeyCreated
}
// import re-created key into account keystore
info.WalletAddress, info.WalletPubKey, err = m.importExtendedKey(extkeys.KeyPurposeWallet, extKey, password)
if err != nil {
return info, err
}
info.ChatAddress = info.WalletAddress
info.ChatPubKey = info.WalletPubKey
return info, nil
}
// VerifyAccountPassword tries to decrypt a given account key file, with a provided password.
// If no error is returned, then account is considered verified.
func (m *DefaultManager) VerifyAccountPassword(keyStoreDir, address, password string) (*types.Key, error) {
var err error
var foundKeyFile []byte
addressObj := types.BytesToAddress(types.FromHex(address))
checkAccountKey := func(path string, fileInfo os.FileInfo) error {
if len(foundKeyFile) > 0 || fileInfo.IsDir() {
return nil
}
rawKeyFile, e := ioutil.ReadFile(path)
if e != nil {
return fmt.Errorf("invalid account key file: %v", e)
}
var accountKey struct {
Address string `json:"address"`
}
if e := json.Unmarshal(rawKeyFile, &accountKey); e != nil {
return fmt.Errorf("failed to read key file: %s", e)
}
if types.HexToAddress("0x"+accountKey.Address).Hex() == addressObj.Hex() {
foundKeyFile = rawKeyFile
}
return nil
}
// locate key within key store directory (address should be within the file)
err = filepath.Walk(keyStoreDir, func(path string, fileInfo os.FileInfo, err error) error {
if err != nil {
return err
}
return checkAccountKey(path, fileInfo)
})
if err != nil {
return nil, fmt.Errorf("cannot traverse key store folder: %v", err)
}
if len(foundKeyFile) == 0 {
return nil, &ErrCannotLocateKeyFile{fmt.Sprintf("cannot locate account for address: %s", addressObj.Hex())}
}
key, err := keystore.DecryptKey(foundKeyFile, password)
if err != nil {
return nil, err
}
// avoid swap attack
if key.Address != addressObj {
return nil, fmt.Errorf("account mismatch: have %s, want %s", key.Address.Hex(), addressObj.Hex())
}
return key, nil
}
// SelectAccount selects current account, by verifying that address has corresponding account which can be decrypted
// using provided password. Once verification is done, all previous identities are removed).
func (m *DefaultManager) SelectAccount(loginParams LoginParams) error {
m.mu.Lock()
defer m.mu.Unlock()
m.accountsGenerator.Reset()
selectedChatAccount, err := m.unlockExtendedKey(loginParams.ChatAddress.String(), loginParams.Password)
if err != nil {
return err
}
m.watchAddresses = loginParams.WatchAddresses
m.mainAccountAddress = loginParams.MainAccount
m.selectedChatAccount = selectedChatAccount
return nil
}
func (m *DefaultManager) SetAccountAddresses(main types.Address, secondary ...types.Address) {
m.watchAddresses = []types.Address{main}
m.watchAddresses = append(m.watchAddresses, secondary...)
m.mainAccountAddress = main
}
// SetChatAccount initializes selectedChatAccount with privKey
func (m *DefaultManager) SetChatAccount(privKey *ecdsa.PrivateKey) error {
m.mu.Lock()
defer m.mu.Unlock()
address := crypto.PubkeyToAddress(privKey.PublicKey)
id, err := uuid.NewRandom()
if err != nil {
return err
}
key := &types.Key{
ID: id,
Address: address,
PrivateKey: privKey,
}
m.selectedChatAccount = &SelectedExtKey{
Address: address,
AccountKey: key,
}
return nil
}
// MainAccountAddress returns main account address set during login
func (m *DefaultManager) MainAccountAddress() (types.Address, error) {
m.mu.RLock()
defer m.mu.RUnlock()
if m.mainAccountAddress == zeroAddress {
return zeroAddress, ErrNoAccountSelected
}
return m.mainAccountAddress, nil
}
// WatchAddresses returns currently selected watch addresses.
func (m *DefaultManager) WatchAddresses() []types.Address {
m.mu.RLock()
defer m.mu.RUnlock()
return m.watchAddresses
}
// SelectedChatAccount returns currently selected chat account
func (m *DefaultManager) SelectedChatAccount() (*SelectedExtKey, error) {
m.mu.RLock()
defer m.mu.RUnlock()
if m.selectedChatAccount == nil {
return nil, ErrNoAccountSelected
}
return m.selectedChatAccount, nil
}
// Logout clears selected accounts.
func (m *DefaultManager) Logout() {
m.mu.Lock()
defer m.mu.Unlock()
m.accountsGenerator.Reset()
m.mainAccountAddress = zeroAddress
m.watchAddresses = nil
m.selectedChatAccount = nil
}
// ImportAccount imports the account specified with privateKey.
func (m *DefaultManager) ImportAccount(privateKey *ecdsa.PrivateKey, password string) (types.Address, error) {
if m.keystore == nil {
return types.Address{}, ErrAccountKeyStoreMissing
}
account, err := m.keystore.ImportECDSA(privateKey, password)
return account.Address, err
}
// ImportSingleExtendedKey imports an extended key setting it in both the PrivateKey and ExtendedKey fields
// of the Key struct.
// ImportExtendedKey is used in older version of Status where PrivateKey is set to be the BIP44 key at index 0,
// and ExtendedKey is the extended key of the BIP44 key at index 1.
func (m *DefaultManager) ImportSingleExtendedKey(extKey *extkeys.ExtendedKey, password string) (address, pubKey string, err error) {
if m.keystore == nil {
return "", "", ErrAccountKeyStoreMissing
}
// imports extended key, create key file (if necessary)
account, err := m.keystore.ImportSingleExtendedKey(extKey, password)
if err != nil {
return "", "", err
}
address = account.Address.Hex()
// obtain public key to return
account, key, err := m.keystore.AccountDecryptedKey(account, password)
if err != nil {
return address, "", err
}
pubKey = types.EncodeHex(crypto.FromECDSAPub(&key.PrivateKey.PublicKey))
return
}
// importExtendedKey processes incoming extended key, extracts required info and creates corresponding account key.
// Once account key is formed, that key is put (if not already) into keystore i.e. key is *encoded* into key file.
func (m *DefaultManager) importExtendedKey(keyPurpose extkeys.KeyPurpose, extKey *extkeys.ExtendedKey, password string) (address, pubKey string, err error) {
if m.keystore == nil {
return "", "", ErrAccountKeyStoreMissing
}
// imports extended key, create key file (if necessary)
account, err := m.keystore.ImportExtendedKeyForPurpose(keyPurpose, extKey, password)
if err != nil {
return "", "", err
}
address = account.Address.Hex()
// obtain public key to return
account, key, err := m.keystore.AccountDecryptedKey(account, password)
if err != nil {
return address, "", err
}
pubKey = types.EncodeHex(crypto.FromECDSAPub(&key.PrivateKey.PublicKey))
return
}
// Accounts returns list of addresses for selected account, including
// subaccounts.
func (m *DefaultManager) Accounts() ([]types.Address, error) {
m.mu.RLock()
defer m.mu.RUnlock()
addresses := make([]types.Address, 0)
if m.mainAccountAddress != zeroAddress {
addresses = append(addresses, m.mainAccountAddress)
}
return addresses, nil
}
// StartOnboarding starts the onboarding process generating accountsCount accounts and returns a slice of OnboardingAccount.
func (m *DefaultManager) StartOnboarding(accountsCount, mnemonicPhraseLength int) ([]*OnboardingAccount, error) {
m.mu.Lock()
defer m.mu.Unlock()
onboarding, err := NewOnboarding(accountsCount, mnemonicPhraseLength)
if err != nil {
return nil, err
}
m.onboarding = onboarding
return m.onboarding.Accounts(), nil
}
// RemoveOnboarding reset the current onboarding struct setting it to nil and deleting the accounts from memory.
func (m *DefaultManager) RemoveOnboarding() {
m.mu.Lock()
defer m.mu.Unlock()
m.onboarding = nil
}
// ImportOnboardingAccount imports the account specified by id and encrypts it with password.
func (m *DefaultManager) ImportOnboardingAccount(id string, password string) (Info, string, error) {
var info Info
m.mu.Lock()
defer m.mu.Unlock()
if m.onboarding == nil {
return info, "", ErrOnboardingNotStarted
}
acc, err := m.onboarding.Account(id)
if err != nil {
return info, "", err
}
info, err = m.RecoverAccount(password, acc.mnemonic)
if err != nil {
return info, "", err
}
m.onboarding = nil
return info, acc.mnemonic, nil
}
// AddressToDecryptedAccount tries to load decrypted key for a given account.
// The running node, has a keystore directory which is loaded on start. Key file
// for a given address is expected to be in that directory prior to node start.
func (m *DefaultManager) AddressToDecryptedAccount(address, password string) (types.Account, *types.Key, error) {
if m.keystore == nil {
return types.Account{}, nil, ErrAccountKeyStoreMissing
}
account, err := ParseAccountString(address)
if err != nil {
return types.Account{}, nil, ErrAddressToAccountMappingFailure
}
account, key, err := m.keystore.AccountDecryptedKey(account, password)
if err != nil {
err = fmt.Errorf("%s: %s", ErrAccountToKeyMappingFailure, err)
}
return account, key, err
}
func (m *DefaultManager) unlockExtendedKey(address, password string) (*SelectedExtKey, error) {
account, accountKey, err := m.AddressToDecryptedAccount(address, password)
if err != nil {
return nil, err
}
selectedExtendedKey := &SelectedExtKey{
Address: account.Address,
AccountKey: accountKey,
}
return selectedExtendedKey, nil
}
func (m *DefaultManager) MigrateKeyStoreDir(oldDir, newDir string, addresses []string) error {
paths := []string{}
addressesMap := map[string]struct{}{}
for _, address := range addresses {
addressesMap[address] = struct{}{}
}
checkFile := func(path string, fileInfo os.FileInfo) error {
if fileInfo.IsDir() || filepath.Dir(path) != oldDir {
return nil
}
rawKeyFile, err := ioutil.ReadFile(path)
if err != nil {
return fmt.Errorf("invalid account key file: %v", err)
}
var accountKey struct {
Address string `json:"address"`
}
if err := json.Unmarshal(rawKeyFile, &accountKey); err != nil {
return fmt.Errorf("failed to read key file: %s", err)
}
address := types.HexToAddress("0x" + accountKey.Address).Hex()
if _, ok := addressesMap[address]; ok {
paths = append(paths, path)
}
return nil
}
err := filepath.Walk(oldDir, func(path string, fileInfo os.FileInfo, err error) error {
if err != nil {
return err
}
return checkFile(path, fileInfo)
})
if err != nil {
return fmt.Errorf("cannot traverse key store folder: %v", err)
}
for _, path := range paths {
_, fileName := filepath.Split(path)
newPath := filepath.Join(newDir, fileName)
err := os.Rename(path, newPath)
if err != nil {
return err
}
}
return nil
}
func (m *DefaultManager) ReEncryptKey(rawKey []byte, pass string, newPass string) (reEncryptedKey []byte, e error) {
cryptoJSON, e := keystore.RawKeyToCryptoJSON(rawKey)
if e != nil {
return reEncryptedKey, fmt.Errorf("convert to crypto json error: %v", e)
}
decryptedKey, e := keystore.DecryptKey(rawKey, pass)
if e != nil {
return reEncryptedKey, fmt.Errorf("decryption error: %v", e)
}
if cryptoJSON.KDFParams["n"] == nil || cryptoJSON.KDFParams["p"] == nil {
return reEncryptedKey, fmt.Errorf("Unable to determine `n` or `p`: %v", e)
}
n := int(cryptoJSON.KDFParams["n"].(float64))
p := int(cryptoJSON.KDFParams["p"].(float64))
gethKey := gethkeystore.Key{
Id: decryptedKey.ID,
Address: gethcommon.Address(decryptedKey.Address),
PrivateKey: decryptedKey.PrivateKey,
ExtendedKey: decryptedKey.ExtendedKey,
SubAccountIndex: decryptedKey.SubAccountIndex,
}
return gethkeystore.EncryptKey(&gethKey, newPass, n, p)
}
func (m *DefaultManager) ReEncryptKeyStoreDir(keyDirPath, oldPass, newPass string) error {
rencryptFileAtPath := func(tempKeyDirPath, path string, fileInfo os.FileInfo) error {
if fileInfo.IsDir() {
return nil
}
rawKeyFile, e := ioutil.ReadFile(path)
if e != nil {
return fmt.Errorf("invalid account key file: %v", e)
}
reEncryptedKey, e := m.ReEncryptKey(rawKeyFile, oldPass, newPass)
if e != nil {
return fmt.Errorf("unable to re-encrypt key file: %v, path: %s, name: %s", e, path, fileInfo.Name())
}
tempWritePath := filepath.Join(tempKeyDirPath, fileInfo.Name())
e = ioutil.WriteFile(tempWritePath, reEncryptedKey, fileInfo.Mode().Perm())
if e != nil {
return fmt.Errorf("unable write key file: %v", e)
}
return nil
}
keyDirPath = strings.TrimSuffix(keyDirPath, "/")
keyDirPath = strings.TrimSuffix(keyDirPath, "\\")
keyParent, keyDirName := filepath.Split(keyDirPath)
// backupKeyDirName used to store existing keys before final write
backupKeyDirName := keyDirName + "-backup"
// tempKeyDirName used to put re-encrypted keys
tempKeyDirName := keyDirName + "-re-encrypted"
backupKeyDirPath := filepath.Join(keyParent, backupKeyDirName)
tempKeyDirPath := filepath.Join(keyParent, tempKeyDirName)
// create temp key dir
err := os.MkdirAll(tempKeyDirPath, os.ModePerm)
if err != nil {
return fmt.Errorf("mkdirall error: %v, tempKeyDirPath: %s", err, tempKeyDirPath)
}
err = filepath.Walk(keyDirPath, func(path string, fileInfo os.FileInfo, err error) error {
if err != nil {
os.RemoveAll(tempKeyDirPath)
return fmt.Errorf("walk callback error: %v", err)
}
return rencryptFileAtPath(tempKeyDirPath, path, fileInfo)
})
if err != nil {
os.RemoveAll(tempKeyDirPath)
return fmt.Errorf("walk error: %v", err)
}
// move existing keys
err = os.Rename(keyDirPath, backupKeyDirPath)
if err != nil {
os.RemoveAll(tempKeyDirPath)
return fmt.Errorf("unable to rename keyDirPath to backupKeyDirPath: %v", err)
}
// move tempKeyDirPath to keyDirPath
err = os.Rename(tempKeyDirPath, keyDirPath)
if err != nil {
// if this happens, then the app is probably bricked, because the keystore won't exist anymore
// try to restore from backup
_ = os.Rename(backupKeyDirPath, keyDirPath)
return fmt.Errorf("unable to rename tempKeyDirPath to keyDirPath: %v", err)
}
// remove temp and backup folders and their contents
err = os.RemoveAll(tempKeyDirPath)
if err != nil {
// the re-encryption is complete so we don't throw
log.Error("unable to delete tempKeyDirPath, manual cleanup required")
}
err = os.RemoveAll(backupKeyDirPath)
if err != nil {
// the re-encryption is complete so we don't throw
log.Error("unable to delete backupKeyDirPath, manual cleanup required")
}
return nil
}
func (m *DefaultManager) DeleteAccount(address types.Address) error {
return m.keystore.Delete(types.Account{Address: address})
}
func (m *DefaultManager) GetVerifiedWalletAccount(db *accounts.Database, address, password string) (*SelectedExtKey, error) {
exists, err := db.AddressExists(types.HexToAddress(address))
if err != nil {
return nil, err
}
if !exists {
return nil, errors.New("account doesn't exist")
}
key, err := m.VerifyAccountPassword(m.Keydir, address, password)
if _, ok := err.(*ErrCannotLocateKeyFile); ok {
key, err = m.generatePartialAccountKey(db, address, password)
if err != nil {
return nil, err
}
}
if err != nil {
return nil, err
}
return &SelectedExtKey{
Address: key.Address,
AccountKey: key,
}, nil
}
func (m *DefaultManager) generatePartialAccountKey(db *accounts.Database, address string, password string) (*types.Key, error) {
dbPath, err := db.GetPath(types.HexToAddress(address))
path := "m/" + dbPath[strings.LastIndex(dbPath, "/")+1:]
if err != nil {
return nil, err
}
rootAddress, err := db.GetWalletRootAddress()
if err != nil {
return nil, err
}
info, err := m.AccountsGenerator().LoadAccount(rootAddress.Hex(), password)
if err != nil {
return nil, err
}
masterID := info.ID
accInfosMap, err := m.AccountsGenerator().StoreDerivedAccounts(masterID, password, []string{path})
if err != nil {
return nil, err
}
_, key, err := m.AddressToDecryptedAccount(accInfosMap[path].Address, password)
if err != nil {
return nil, err
}
return key, nil
}
func (m *DefaultManager) Recover(rpcParams RecoverParams) (addr types.Address, err error) {
ctx, cancel := context.WithTimeout(context.Background(), m.rpcTimeout)
defer cancel()
var gethAddr gethcommon.Address
err = m.rpcClient.CallContextIgnoringLocalHandlers(
ctx,
&gethAddr,
m.rpcClient.UpstreamChainID,
params.PersonalRecoverMethodName,
rpcParams.Message, rpcParams.Signature)
addr = types.Address(gethAddr)
return
}
func (m *DefaultManager) CanRecover(rpcParams RecoverParams, revealedAddress types.Address) (bool, error) {
recovered, err := m.Recover(rpcParams)
if err != nil {
return false, err
}
return recovered == revealedAddress, nil
}
func (m *DefaultManager) Sign(rpcParams SignParams, verifiedAccount *SelectedExtKey) (result types.HexBytes, err error) {
if !strings.EqualFold(rpcParams.Address, verifiedAccount.Address.Hex()) {
err = ErrInvalidPersonalSignAccount
return
}
ctx, cancel := context.WithTimeout(context.Background(), m.rpcTimeout)
defer cancel()
var gethResult hexutil.Bytes
err = m.rpcClient.CallContextIgnoringLocalHandlers(
ctx,
&gethResult,
m.rpcClient.UpstreamChainID,
params.PersonalSignMethodName,
rpcParams.Data, rpcParams.Address, rpcParams.Password)
result = types.HexBytes(gethResult)
return
}

View File

@@ -0,0 +1,51 @@
package account
import (
"time"
"github.com/ethereum/go-ethereum/accounts"
"github.com/status-im/status-go/account/generator"
"github.com/status-im/status-go/rpc"
)
// GethManager represents account manager interface.
type GethManager struct {
*DefaultManager
gethAccManager *accounts.Manager
}
// NewGethManager returns new node account manager.
func NewGethManager() *GethManager {
m := &GethManager{}
m.DefaultManager = &DefaultManager{accountsGenerator: generator.New(m)}
return m
}
func (m *GethManager) SetRPCClient(rpcClient *rpc.Client, rpcTimeout time.Duration) {
m.DefaultManager.rpcClient = rpcClient
m.DefaultManager.rpcTimeout = rpcTimeout
}
// InitKeystore sets key manager and key store.
func (m *GethManager) InitKeystore(keydir string) error {
m.mu.Lock()
defer m.mu.Unlock()
var err error
m.gethAccManager, err = makeAccountManager(keydir)
if err != nil {
return err
}
m.keystore, err = makeKeyStore(m.gethAccManager)
m.Keydir = keydir
return err
}
func (m *GethManager) GetManager() *accounts.Manager {
m.mu.RLock()
defer m.mu.RUnlock()
return m.gethAccManager
}

View File

@@ -0,0 +1,23 @@
package account
import (
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
)
func CreateAddress() (address, pubKey, privKey string, err error) {
key, err := crypto.GenerateKey()
if err != nil {
return "", "", "", err
}
privKeyBytes := crypto.FromECDSA(key)
pubKeyBytes := crypto.FromECDSAPub(&key.PublicKey)
addressBytes := crypto.PubkeyToAddress(key.PublicKey)
privKey = types.EncodeHex(privKeyBytes)
pubKey = types.EncodeHex(pubKeyBytes)
address = addressBytes.Hex()
return
}

View File

@@ -0,0 +1,43 @@
# Account Generator
The Account Generator is used to generate, import, derive child keys, and store accounts.
It is instantiated in the `account.Manager` struct and it's accessible from the `lib` and `mobile`
package through functions with the `MultiAccount` prefix:
* MultiAccountGenerate
* MultiAccountGenerateAndDeriveAddresses
* MultiAccountImportMnemonic
* MultiAccountDeriveAddresses
* MultiAccountStoreDerivedAccounts
* MultiAccountImportPrivateKey
* MultiAccountStoreAccount
* MultiAccountLoadAccount
* MultiAccountReset
Using `Generate` and `ImportMnemonic`, a master key is loaded in memory and a random temporarily id is returned.
Bare in mind these accounts are not saved. They are in memory until `StoreAccount` or `StoreDerivedAccounts` are called.
Calling `Reset` or restarting the application will remove everything from memory.
Logging-in and Logging-out will do the same.
Since `Generate` and `ImportMnemonic` create extended keys, we can use those keys to derive new child keys.
`MultiAccountDeriveAddresses(id, paths)` returns a list of addresses/pubKey, one for each path.
This can be used to check balances on those addresses and show them to the user.
Once the user is happy with some specific derivation paths, we can store them using `StoreDerivedAccounts(id, passwordToEncryptKey, paths)`.
`StoreDerivedAccounts` returns an address/pubKey for each path. The address can be use in the future to load them in memory again.
Calling `StoreDerivedAccounts` will encrypt and store the keys, each one in a keystore json file, and remove all the keys from memory.
Since they are derived from an extended key, they are extended keys too, so they can be used in the future to derive more child keys.
`StoreAccount` stores the key identified by its ID, so in case the key comes from `Generate` or `ImportPrivateKey`, it will store the master key.
In general we want to avoid saving master keys, so we should only use `StoreDerivedAccounts` for extended keys, and `StoreAccount` for normal keys.
Calling `Load(address, password)` will unlock the key specified by addresses using password, and load it in memory.
`Load` returns a new id that can be used again with DeriveAddresses, `StoreAccount`, and `StoreDerivedAccounts`.
`ImportPrivateKey` imports a raw private key specified by its hex form.
It's not an extended key, so it can't be used to derive child addresses.
You can call `DeriveAddresses` to derive the address/pubKey of a normal key passing an empty string as derivation path.
`StoreAccount` will save the key without deriving a child key.

View File

@@ -0,0 +1,171 @@
package generator
import (
"crypto/ecdsa"
"crypto/sha256"
"encoding/json"
"time"
accountJson "github.com/status-im/status-go/account/json"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/extkeys"
"github.com/status-im/status-go/multiaccounts"
)
type Account struct {
privateKey *ecdsa.PrivateKey
extendedKey *extkeys.ExtendedKey
}
func NewAccount(privateKey *ecdsa.PrivateKey, extKey *extkeys.ExtendedKey) Account {
if privateKey == nil {
privateKey = extKey.ToECDSA()
}
return Account{
privateKey: privateKey,
extendedKey: extKey,
}
}
func (a *Account) ToAccountInfo() AccountInfo {
privateKeyHex := types.EncodeHex(crypto.FromECDSA(a.privateKey))
publicKeyHex := types.EncodeHex(crypto.FromECDSAPub(&a.privateKey.PublicKey))
addressHex := crypto.PubkeyToAddress(a.privateKey.PublicKey).Hex()
return AccountInfo{
PrivateKey: privateKeyHex,
PublicKey: publicKeyHex,
Address: addressHex,
}
}
func (a *Account) ToIdentifiedAccountInfo(id string) IdentifiedAccountInfo {
info := a.ToAccountInfo()
keyUID := sha256.Sum256(crypto.FromECDSAPub(&a.privateKey.PublicKey))
keyUIDHex := types.EncodeHex(keyUID[:])
return IdentifiedAccountInfo{
AccountInfo: info,
ID: id,
KeyUID: keyUIDHex,
}
}
func (a *Account) ToGeneratedAccountInfo(id string, mnemonic string) GeneratedAccountInfo {
idInfo := a.ToIdentifiedAccountInfo(id)
return GeneratedAccountInfo{
IdentifiedAccountInfo: idInfo,
Mnemonic: mnemonic,
}
}
// AccountInfo contains a PublicKey and an Address of an account.
type AccountInfo struct {
PrivateKey string `json:"privateKey"`
PublicKey string `json:"publicKey"`
Address string `json:"address"`
}
func (a AccountInfo) MarshalJSON() ([]byte, error) {
type Alias AccountInfo
ext, err := accountJson.ExtendStructWithPubKeyData(a.PublicKey, Alias(a))
if err != nil {
return nil, err
}
return json.Marshal(ext)
}
// IdentifiedAccountInfo contains AccountInfo and the ID of an account.
type IdentifiedAccountInfo struct {
AccountInfo
ID string `json:"id"`
// KeyUID is calculated as sha256 of the master public key and used for key
// identification. This is the only information available about the master
// key stored on a keycard before the card is paired.
// KeyUID name is chosen over KeyID in order to make it consistent with
// the name already used in Status and Keycard codebases.
KeyUID string `json:"keyUid"`
}
func (i IdentifiedAccountInfo) MarshalJSON() ([]byte, error) {
accountInfoJSON, err := i.AccountInfo.MarshalJSON()
if err != nil {
return nil, err
}
type info struct {
ID string `json:"id"`
KeyUID string `json:"keyUid"`
}
infoJSON, err := json.Marshal(info{
ID: i.ID,
KeyUID: i.KeyUID,
})
if err != nil {
return nil, err
}
infoJSON[0] = ','
return append(accountInfoJSON[:len(accountInfoJSON)-1], infoJSON...), nil
}
func (i *IdentifiedAccountInfo) ToMultiAccount() *multiaccounts.Account {
return &multiaccounts.Account{
Timestamp: time.Now().Unix(),
KeyUID: i.KeyUID,
}
}
// GeneratedAccountInfo contains IdentifiedAccountInfo and the mnemonic of an account.
type GeneratedAccountInfo struct {
IdentifiedAccountInfo
Mnemonic string `json:"mnemonic"`
}
func (g GeneratedAccountInfo) MarshalJSON() ([]byte, error) {
accountInfoJSON, err := g.IdentifiedAccountInfo.MarshalJSON()
if err != nil {
return nil, err
}
type info struct {
Mnemonic string `json:"mnemonic"`
}
infoJSON, err := json.Marshal(info{
Mnemonic: g.Mnemonic,
})
if err != nil {
return nil, err
}
infoJSON[0] = ','
return append(accountInfoJSON[:len(accountInfoJSON)-1], infoJSON...), nil
}
func (g GeneratedAccountInfo) toGeneratedAndDerived(derived map[string]AccountInfo) GeneratedAndDerivedAccountInfo {
return GeneratedAndDerivedAccountInfo{
GeneratedAccountInfo: g,
Derived: derived,
}
}
// GeneratedAndDerivedAccountInfo contains GeneratedAccountInfo and derived AccountInfo mapped by derivation path.
type GeneratedAndDerivedAccountInfo struct {
GeneratedAccountInfo
Derived map[string]AccountInfo `json:"derived"`
}
func (g GeneratedAndDerivedAccountInfo) MarshalJSON() ([]byte, error) {
accountInfoJSON, err := g.GeneratedAccountInfo.MarshalJSON()
if err != nil {
return nil, err
}
type info struct {
Derived map[string]AccountInfo `json:"derived"`
}
infoJSON, err := json.Marshal(info{
Derived: g.Derived,
})
if err != nil {
return nil, err
}
infoJSON[0] = ','
return append(accountInfoJSON[:len(accountInfoJSON)-1], infoJSON...), nil
}

View File

@@ -0,0 +1,352 @@
package generator
import (
"crypto/ecdsa"
"errors"
"fmt"
"strings"
"sync"
"github.com/pborman/uuid"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/keystore"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/extkeys"
)
var (
// ErrAccountNotFoundByID is returned when the selected account doesn't exist in memory.
ErrAccountNotFoundByID = errors.New("account not found")
// ErrAccountCannotDeriveChildKeys is returned when trying to derive child accounts from a normal key.
ErrAccountCannotDeriveChildKeys = errors.New("selected account cannot derive child keys")
// ErrAccountManagerNotSet is returned when the account mananger instance is not set.
ErrAccountManagerNotSet = errors.New("account manager not set")
)
type AccountManager interface {
AddressToDecryptedAccount(address, password string) (types.Account, *types.Key, error)
ImportSingleExtendedKey(extKey *extkeys.ExtendedKey, password string) (address, pubKey string, err error)
ImportAccount(privateKey *ecdsa.PrivateKey, password string) (types.Address, error)
}
type Generator struct {
am AccountManager
accounts map[string]*Account
sync.Mutex
}
func New(am AccountManager) *Generator {
return &Generator{
am: am,
accounts: make(map[string]*Account),
}
}
func (g *Generator) Generate(mnemonicPhraseLength int, n int, bip39Passphrase string) ([]GeneratedAccountInfo, error) {
entropyStrength, err := MnemonicPhraseLengthToEntropyStrength(mnemonicPhraseLength)
if err != nil {
return nil, err
}
infos := make([]GeneratedAccountInfo, 0)
for i := 0; i < n; i++ {
mnemonic := extkeys.NewMnemonic()
mnemonicPhrase, err := mnemonic.MnemonicPhrase(entropyStrength, extkeys.EnglishLanguage)
if err != nil {
return nil, fmt.Errorf("can not create mnemonic seed: %v", err)
}
info, err := g.ImportMnemonic(mnemonicPhrase, bip39Passphrase)
if err != nil {
return nil, err
}
infos = append(infos, info)
}
return infos, err
}
func (g *Generator) CreateAccountFromPrivateKey(privateKeyHex string) (IdentifiedAccountInfo, error) {
privateKeyHex = strings.TrimPrefix(privateKeyHex, "0x")
privateKey, err := crypto.HexToECDSA(privateKeyHex)
if err != nil {
return IdentifiedAccountInfo{}, err
}
acc := &Account{
privateKey: privateKey,
}
return acc.ToIdentifiedAccountInfo(""), nil
}
func (g *Generator) ImportPrivateKey(privateKeyHex string) (IdentifiedAccountInfo, error) {
privateKeyHex = strings.TrimPrefix(privateKeyHex, "0x")
privateKey, err := crypto.HexToECDSA(privateKeyHex)
if err != nil {
return IdentifiedAccountInfo{}, err
}
acc := &Account{
privateKey: privateKey,
}
id := g.addAccount(acc)
return acc.ToIdentifiedAccountInfo(id), nil
}
func (g *Generator) ImportJSONKey(json string, password string) (IdentifiedAccountInfo, error) {
key, err := keystore.DecryptKey([]byte(json), password)
if err != nil {
return IdentifiedAccountInfo{}, err
}
acc := &Account{
privateKey: key.PrivateKey,
}
id := g.addAccount(acc)
return acc.ToIdentifiedAccountInfo(id), nil
}
func (g *Generator) CreateAccountFromMnemonicAndDeriveAccountsForPaths(mnemonicPhrase string, bip39Passphrase string, paths []string) (GeneratedAndDerivedAccountInfo, error) {
mnemonic := extkeys.NewMnemonic()
masterExtendedKey, err := extkeys.NewMaster(mnemonic.MnemonicSeed(mnemonicPhrase, bip39Passphrase))
if err != nil {
return GeneratedAndDerivedAccountInfo{}, fmt.Errorf("can not create master extended key: %v", err)
}
acc := &Account{
privateKey: masterExtendedKey.ToECDSA(),
extendedKey: masterExtendedKey,
}
derivedAccountsInfo := make(map[string]AccountInfo)
if len(paths) > 0 {
derivedAccounts, err := g.deriveChildAccounts(acc, paths)
if err != nil {
return GeneratedAndDerivedAccountInfo{}, err
}
for pathString, childAccount := range derivedAccounts {
derivedAccountsInfo[pathString] = childAccount.ToAccountInfo()
}
}
accInfo := acc.ToGeneratedAccountInfo("", mnemonicPhrase)
return accInfo.toGeneratedAndDerived(derivedAccountsInfo), nil
}
func (g *Generator) ImportMnemonic(mnemonicPhrase string, bip39Passphrase string) (GeneratedAccountInfo, error) {
mnemonic := extkeys.NewMnemonic()
masterExtendedKey, err := extkeys.NewMaster(mnemonic.MnemonicSeed(mnemonicPhrase, bip39Passphrase))
if err != nil {
return GeneratedAccountInfo{}, fmt.Errorf("can not create master extended key: %v", err)
}
acc := &Account{
privateKey: masterExtendedKey.ToECDSA(),
extendedKey: masterExtendedKey,
}
id := g.addAccount(acc)
return acc.ToGeneratedAccountInfo(id, mnemonicPhrase), nil
}
func (g *Generator) GenerateAndDeriveAddresses(mnemonicPhraseLength int, n int, bip39Passphrase string, pathStrings []string) ([]GeneratedAndDerivedAccountInfo, error) {
masterAccounts, err := g.Generate(mnemonicPhraseLength, n, bip39Passphrase)
if err != nil {
return nil, err
}
accs := make([]GeneratedAndDerivedAccountInfo, n)
for i := 0; i < len(masterAccounts); i++ {
acc := masterAccounts[i]
derived, err := g.DeriveAddresses(acc.ID, pathStrings)
if err != nil {
return nil, err
}
accs[i] = acc.toGeneratedAndDerived(derived)
}
return accs, nil
}
func (g *Generator) DeriveAddresses(accountID string, pathStrings []string) (map[string]AccountInfo, error) {
acc, err := g.findAccount(accountID)
if err != nil {
return nil, err
}
pathAccounts, err := g.deriveChildAccounts(acc, pathStrings)
if err != nil {
return nil, err
}
pathAccountsInfo := make(map[string]AccountInfo)
for pathString, childAccount := range pathAccounts {
pathAccountsInfo[pathString] = childAccount.ToAccountInfo()
}
return pathAccountsInfo, nil
}
func (g *Generator) StoreAccount(accountID string, password string) (AccountInfo, error) {
if g.am == nil {
return AccountInfo{}, ErrAccountManagerNotSet
}
acc, err := g.findAccount(accountID)
if err != nil {
return AccountInfo{}, err
}
return g.store(acc, password)
}
func (g *Generator) StoreDerivedAccounts(accountID string, password string, pathStrings []string) (map[string]AccountInfo, error) {
if g.am == nil {
return nil, ErrAccountManagerNotSet
}
acc, err := g.findAccount(accountID)
if err != nil {
return nil, err
}
pathAccounts, err := g.deriveChildAccounts(acc, pathStrings)
if err != nil {
return nil, err
}
pathAccountsInfo := make(map[string]AccountInfo)
for pathString, childAccount := range pathAccounts {
info, err := g.store(childAccount, password)
if err != nil {
return nil, err
}
pathAccountsInfo[pathString] = info
}
return pathAccountsInfo, nil
}
func (g *Generator) LoadAccount(address string, password string) (IdentifiedAccountInfo, error) {
if g.am == nil {
return IdentifiedAccountInfo{}, ErrAccountManagerNotSet
}
_, key, err := g.am.AddressToDecryptedAccount(address, password)
if err != nil {
return IdentifiedAccountInfo{}, err
}
if err := ValidateKeystoreExtendedKey(key); err != nil {
return IdentifiedAccountInfo{}, err
}
acc := &Account{
privateKey: key.PrivateKey,
extendedKey: key.ExtendedKey,
}
id := g.addAccount(acc)
return acc.ToIdentifiedAccountInfo(id), nil
}
func (g *Generator) deriveChildAccounts(acc *Account, pathStrings []string) (map[string]*Account, error) {
pathAccounts := make(map[string]*Account)
for _, pathString := range pathStrings {
childAccount, err := g.deriveChildAccount(acc, pathString)
if err != nil {
return pathAccounts, err
}
pathAccounts[pathString] = childAccount
}
return pathAccounts, nil
}
func (g *Generator) deriveChildAccount(acc *Account, pathString string) (*Account, error) {
_, path, err := decodePath(pathString)
if err != nil {
return nil, err
}
if acc.extendedKey.IsZeroed() && len(path) == 0 {
return acc, nil
}
if acc.extendedKey.IsZeroed() {
return nil, ErrAccountCannotDeriveChildKeys
}
childExtendedKey, err := acc.extendedKey.Derive(path)
if err != nil {
return nil, err
}
return &Account{
privateKey: childExtendedKey.ToECDSA(),
extendedKey: childExtendedKey,
}, nil
}
func (g *Generator) store(acc *Account, password string) (AccountInfo, error) {
if acc.extendedKey != nil {
if _, _, err := g.am.ImportSingleExtendedKey(acc.extendedKey, password); err != nil {
return AccountInfo{}, err
}
} else {
if _, err := g.am.ImportAccount(acc.privateKey, password); err != nil {
return AccountInfo{}, err
}
}
return acc.ToAccountInfo(), nil
}
func (g *Generator) addAccount(acc *Account) string {
g.Lock()
defer g.Unlock()
id := uuid.NewRandom().String()
g.accounts[id] = acc
return id
}
// Reset resets the accounts map removing all the accounts from memory.
func (g *Generator) Reset() {
g.Lock()
defer g.Unlock()
g.accounts = make(map[string]*Account)
}
func (g *Generator) findAccount(accountID string) (*Account, error) {
g.Lock()
defer g.Unlock()
acc, ok := g.accounts[accountID]
if !ok {
return nil, ErrAccountNotFoundByID
}
return acc, nil
}

View File

@@ -0,0 +1,226 @@
package generator
import (
"fmt"
"io"
"strconv"
"strings"
)
type startingPoint int
const (
tokenMaster = 0x6D // char m
tokenSeparator = 0x2F // char /
tokenHardened = 0x27 // char '
tokenDot = 0x2E // char .
hardenedStart = 0x80000000 // 2^31
)
const (
startingPointMaster startingPoint = iota + 1
startingPointCurrent
startingPointParent
)
type parseFunc = func() error
type pathDecoder struct {
s string
r *strings.Reader
f parseFunc
pos int
path []uint32
start startingPoint
currentToken string
currentTokenHardened bool
}
func newPathDecoder(path string) (*pathDecoder, error) {
d := &pathDecoder{
s: path,
r: strings.NewReader(path),
}
if err := d.reset(); err != nil {
return nil, err
}
return d, nil
}
func (d *pathDecoder) reset() error {
_, err := d.r.Seek(0, io.SeekStart)
if err != nil {
return err
}
d.pos = 0
d.start = startingPointCurrent
d.f = d.parseStart
d.path = make([]uint32, 0)
d.resetCurrentToken()
return nil
}
func (d *pathDecoder) resetCurrentToken() {
d.currentToken = ""
d.currentTokenHardened = false
}
func (d *pathDecoder) parse() (startingPoint, []uint32, error) {
for {
err := d.f()
if err != nil {
if err == io.EOF {
err = nil
} else {
err = fmt.Errorf("error parsing derivation path %s; at position %d, %s", d.s, d.pos, err.Error())
}
return d.start, d.path, err
}
}
}
func (d *pathDecoder) readByte() (byte, error) {
b, err := d.r.ReadByte()
if err != nil {
return b, err
}
d.pos++
return b, nil
}
func (d *pathDecoder) unreadByte() error {
err := d.r.UnreadByte()
if err != nil {
return err
}
d.pos--
return nil
}
func (d *pathDecoder) parseStart() error {
b, err := d.readByte()
if err != nil {
return err
}
if b == tokenMaster {
d.start = startingPointMaster
d.f = d.parseSeparator
return nil
}
if b == tokenDot {
b2, err := d.readByte()
if err != nil {
return err
}
if b2 == tokenDot {
d.f = d.parseSeparator
d.start = startingPointParent
return nil
}
d.f = d.parseSeparator
d.start = startingPointCurrent
return d.unreadByte()
}
d.f = d.parseSegment
return d.unreadByte()
}
func (d *pathDecoder) saveSegment() error {
if len(d.currentToken) > 0 {
i, err := strconv.ParseUint(d.currentToken, 10, 32)
if err != nil {
return err
}
if i >= hardenedStart {
d.pos -= len(d.currentToken) - 1
return fmt.Errorf("index must be lower than 2^31, got %d", i)
}
if d.currentTokenHardened {
i += hardenedStart
}
d.path = append(d.path, uint32(i))
}
d.f = d.parseSegment
d.resetCurrentToken()
return nil
}
func (d *pathDecoder) parseSeparator() error {
b, err := d.readByte()
if err != nil {
return err
}
if b == tokenSeparator {
return d.saveSegment()
}
return fmt.Errorf("expected %s, got %s", string(rune(tokenSeparator)), string(rune(b)))
}
func (d *pathDecoder) parseSegment() error {
b, err := d.readByte()
if err == io.EOF {
if len(d.currentToken) == 0 {
return fmt.Errorf("expected number, got EOF")
}
if newErr := d.saveSegment(); newErr != nil {
return newErr
}
return err
}
if err != nil {
return err
}
if len(d.currentToken) > 0 && b == tokenSeparator {
return d.saveSegment()
}
if len(d.currentToken) > 0 && b == tokenHardened {
d.currentTokenHardened = true
d.f = d.parseSeparator
return nil
}
if b < 0x30 || b > 0x39 {
return fmt.Errorf("expected number, got %s", string(b))
}
d.currentToken = fmt.Sprintf("%s%s", d.currentToken, string(b))
return nil
}
func decodePath(str string) (startingPoint, []uint32, error) {
d, err := newPathDecoder(str)
if err != nil {
return 0, nil, err
}
return d.parse()
}

View File

@@ -0,0 +1,46 @@
package generator
import (
"bytes"
"errors"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/extkeys"
)
var (
// ErrInvalidKeystoreExtendedKey is returned when the decrypted keystore file
// contains some old Status keys.
// The old version used to store the BIP44 account at index 0 as PrivateKey,
// and the BIP44 account at index 1 as ExtendedKey.
// The current version stores the same key as PrivateKey and ExtendedKey.
ErrInvalidKeystoreExtendedKey = errors.New("PrivateKey and ExtendedKey are different")
ErrInvalidMnemonicPhraseLength = errors.New("invalid mnemonic phrase length; valid lengths are 12, 15, 18, 21, and 24")
)
// ValidateKeystoreExtendedKey validates the keystore keys, checking that
// ExtendedKey is the extended key of PrivateKey.
func ValidateKeystoreExtendedKey(key *types.Key) error {
if key.ExtendedKey.IsZeroed() {
return nil
}
if !bytes.Equal(crypto.FromECDSA(key.PrivateKey), crypto.FromECDSA(key.ExtendedKey.ToECDSA())) {
return ErrInvalidKeystoreExtendedKey
}
return nil
}
// MnemonicPhraseLengthToEntropyStrength returns the entropy strength for a given mnemonic length
func MnemonicPhraseLengthToEntropyStrength(length int) (extkeys.EntropyStrength, error) {
if length < 12 || length > 24 || length%3 != 0 {
return 0, ErrInvalidMnemonicPhraseLength
}
bitsLength := length * 11
checksumLength := bitsLength % 32
return extkeys.EntropyStrength(bitsLength - checksumLength), nil
}

View File

@@ -0,0 +1,63 @@
package json
import (
"reflect"
"github.com/status-im/status-go/api/multiformat"
"github.com/status-im/status-go/protocol/identity/emojihash"
)
type PublicKeyData struct {
CompressedKey string `json:"compressedKey"`
EmojiHash []string `json:"emojiHash"`
}
func getPubKeyData(publicKey string) (*PublicKeyData, error) {
compressedKey, err := multiformat.SerializeLegacyKey(publicKey)
if err != nil {
return nil, err
}
emojiHash, err := emojihash.GenerateFor(publicKey)
if err != nil {
return nil, err
}
return &PublicKeyData{compressedKey, emojiHash}, nil
}
func ExtendStructWithPubKeyData(publicKey string, item any) (any, error) {
// If the public key is empty, do not attempt to extend the incoming item
if publicKey == "" {
return item, nil
}
pkd, err := getPubKeyData(publicKey)
if err != nil {
return nil, err
}
// Create a struct with 2 embedded substruct fields in order to circumvent
// "embedded field type cannot be a (pointer to a) type parameter"
// compiler error that arises if we were to use a generic function instead
typ := reflect.StructOf([]reflect.StructField{
{
Name: "Item",
Anonymous: true,
Type: reflect.TypeOf(item),
},
{
Name: "Pkd",
Anonymous: true,
Type: reflect.TypeOf(pkd),
},
})
v := reflect.New(typ).Elem()
v.Field(0).Set(reflect.ValueOf(item))
v.Field(1).Set(reflect.ValueOf(pkd))
s := v.Addr().Interface()
return s, nil
}

View File

@@ -0,0 +1,41 @@
package account
import (
"os"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
gethbridge "github.com/status-im/status-go/eth-node/bridge/geth"
"github.com/status-im/status-go/eth-node/types"
)
// makeAccountManager creates ethereum accounts.Manager with single disk backend and lightweight kdf.
// If keydir is empty new temporary directory with go-ethereum-keystore will be intialized.
func makeAccountManager(keydir string) (manager *accounts.Manager, err error) {
if keydir == "" {
// There is no datadir.
keydir, err = os.MkdirTemp("", "go-ethereum-keystore")
}
if err != nil {
return nil, err
}
if err := os.MkdirAll(keydir, 0700); err != nil {
return nil, err
}
config := accounts.Config{InsecureUnlockAllowed: false}
return accounts.NewManager(&config, keystore.NewKeyStore(keydir, keystore.LightScryptN, keystore.LightScryptP)), nil
}
func makeKeyStore(manager *accounts.Manager) (types.KeyStore, error) {
backends := manager.Backends(keystore.KeyStoreType)
if len(backends) == 0 {
return nil, ErrAccountKeyStoreMissing
}
keyStore, ok := backends[0].(*keystore.KeyStore)
if !ok {
return nil, ErrAccountKeyStoreMissing
}
return gethbridge.WrapKeyStore(keyStore), nil
}

View File

@@ -0,0 +1,114 @@
package account
import (
"fmt"
"github.com/pborman/uuid"
"github.com/status-im/status-go/account/generator"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/extkeys"
)
// OnboardingAccount is returned during onboarding and contains its ID and the mnemonic to re-generate the same account Info keys.
type OnboardingAccount struct {
ID string `json:"id"`
mnemonic string
Info Info `json:"info"`
}
// Onboarding is a struct contains a slice of OnboardingAccount.
type Onboarding struct {
accounts map[string]*OnboardingAccount
}
// NewOnboarding returns a new onboarding struct generating n accounts.
func NewOnboarding(n, mnemonicPhraseLength int) (*Onboarding, error) {
onboarding := &Onboarding{
accounts: make(map[string]*OnboardingAccount),
}
for i := 0; i < n; i++ {
account, err := onboarding.generateAccount(mnemonicPhraseLength)
if err != nil {
return nil, err
}
onboarding.accounts[account.ID] = account
}
return onboarding, nil
}
// Accounts return the list of OnboardingAccount generated.
func (o *Onboarding) Accounts() []*OnboardingAccount {
accounts := make([]*OnboardingAccount, 0)
for _, a := range o.accounts {
accounts = append(accounts, a)
}
return accounts
}
// Account returns an OnboardingAccount by id.
func (o *Onboarding) Account(id string) (*OnboardingAccount, error) {
account, ok := o.accounts[id]
if !ok {
return nil, ErrOnboardingAccountNotFound
}
return account, nil
}
func (o *Onboarding) generateAccount(mnemonicPhraseLength int) (*OnboardingAccount, error) {
entropyStrength, err := generator.MnemonicPhraseLengthToEntropyStrength(mnemonicPhraseLength)
if err != nil {
return nil, err
}
mnemonic := extkeys.NewMnemonic()
mnemonicPhrase, err := mnemonic.MnemonicPhrase(entropyStrength, extkeys.EnglishLanguage)
if err != nil {
return nil, fmt.Errorf("can not create mnemonic seed: %v", err)
}
masterExtendedKey, err := extkeys.NewMaster(mnemonic.MnemonicSeed(mnemonicPhrase, ""))
if err != nil {
return nil, fmt.Errorf("can not create master extended key: %v", err)
}
walletAddress, walletPubKey, err := o.deriveAccount(masterExtendedKey, extkeys.KeyPurposeWallet, 0)
if err != nil {
return nil, err
}
info := Info{
WalletAddress: walletAddress,
WalletPubKey: walletPubKey,
ChatAddress: walletAddress,
ChatPubKey: walletPubKey,
}
uuid := uuid.NewRandom().String()
account := &OnboardingAccount{
ID: uuid,
mnemonic: mnemonicPhrase,
Info: info,
}
return account, nil
}
func (o *Onboarding) deriveAccount(masterExtendedKey *extkeys.ExtendedKey, purpose extkeys.KeyPurpose, index uint32) (string, string, error) {
extendedKey, err := masterExtendedKey.ChildForPurpose(purpose, index)
if err != nil {
return "", "", err
}
privateKeyECDSA := extendedKey.ToECDSA()
address := crypto.PubkeyToAddress(privateKeyECDSA.PublicKey)
publicKeyHex := types.EncodeHex(crypto.FromECDSAPub(&privateKeyECDSA.PublicKey))
return address.Hex(), publicKeyHex, nil
}

130
vendor/github.com/status-im/status-go/account/utils.go generated vendored Normal file
View File

@@ -0,0 +1,130 @@
package account
import (
"encoding/json"
"errors"
"fmt"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/extkeys"
"github.com/status-im/status-go/multiaccounts"
)
// errors
var (
ErrInvalidAccountAddressOrKey = errors.New("cannot parse address or key to valid account address")
ErrInvalidMnemonicPhraseLength = errors.New("invalid mnemonic phrase length; valid lengths are 12, 15, 18, 21, and 24")
)
type LoginParams struct {
ChatAddress types.Address `json:"chatAddress"`
Password string `json:"password"`
MainAccount types.Address `json:"mainAccount"`
WatchAddresses []types.Address `json:"watchAddresses"`
MultiAccount *multiaccounts.Account `json:"multiAccount"`
}
type ErrZeroAddress struct {
field string
}
func (e *ErrZeroAddress) Error() string {
return fmt.Sprintf("%s contains an empty address", e.field)
}
func newErrZeroAddress(field string) *ErrZeroAddress {
return &ErrZeroAddress{
field: field,
}
}
func ParseLoginParams(paramsJSON string) (LoginParams, error) {
var (
params LoginParams
zeroAddress types.Address
)
if err := json.Unmarshal([]byte(paramsJSON), &params); err != nil {
return params, err
}
if params.ChatAddress == zeroAddress {
return params, newErrZeroAddress("ChatAddress")
}
if params.MainAccount == zeroAddress {
return params, newErrZeroAddress("MainAccount")
}
for _, address := range params.WatchAddresses {
if address == zeroAddress {
return params, newErrZeroAddress("WatchAddresses")
}
}
return params, nil
}
// Info contains wallet and chat addresses and public keys of an account.
type Info struct {
WalletAddress string
WalletPubKey string
ChatAddress string
ChatPubKey string
}
// SelectedExtKey is a container for the selected (logged in) external account.
type SelectedExtKey struct {
Address types.Address
AccountKey *types.Key
SubAccounts []types.Account
}
// Hex dumps address of a given extended key as hex string.
func (k *SelectedExtKey) Hex() string {
if k == nil {
return "0x0"
}
return k.Address.Hex()
}
// ParseAccountString parses hex encoded string and returns is as types.Account.
func ParseAccountString(account string) (types.Account, error) {
// valid address, convert to account
if types.IsHexAddress(account) {
return types.Account{Address: types.HexToAddress(account)}, nil
}
return types.Account{}, ErrInvalidAccountAddressOrKey
}
// FromAddress converts account address from string to types.Address.
// The function is useful to format "From" field of send transaction struct.
func FromAddress(accountAddress string) types.Address {
from, err := ParseAccountString(accountAddress)
if err != nil {
return types.Address{}
}
return from.Address
}
// ToAddress converts account address from string to *common.Address.
// The function is useful to format "To" field of send transaction struct.
func ToAddress(accountAddress string) *types.Address {
to, err := ParseAccountString(accountAddress)
if err != nil {
return nil
}
return &to.Address
}
func GetRandomMnemonic() (string, error) {
// generate mnemonic phrase
mn := extkeys.NewMnemonic()
mnemonic, err := mn.MnemonicPhrase(extkeys.EntropyStrength128, extkeys.EnglishLanguage)
if err != nil {
return "", fmt.Errorf("can not create mnemonic seed: %v", err)
}
return mnemonic, nil
}

1
vendor/github.com/status-im/status-go/api/.gitignore generated vendored Normal file
View File

@@ -0,0 +1 @@
accounts.sql*

42
vendor/github.com/status-im/status-go/api/app_state.go generated vendored Normal file
View File

@@ -0,0 +1,42 @@
package api
import (
"fmt"
"strings"
)
// appState represents if the app is in foreground, background or some other state
type appState string
func (a appState) String() string {
return string(a)
}
// Specific app states
// see https://facebook.github.io/react-native/docs/appstate.html
const (
appStateForeground = appState("active") // these constant values are kept in sync with React Native
appStateBackground = appState("background")
appStateInactive = appState("inactive")
appStateInvalid = appState("")
)
// validAppStates returns an immutable set of valid states.
func validAppStates() []appState {
return []appState{appStateInactive, appStateBackground, appStateForeground}
}
// parseAppState creates AppState from a string
func parseAppState(stateString string) (appState, error) {
// a bit of cleaning up
stateString = strings.ToLower(strings.TrimSpace(stateString))
for _, state := range validAppStates() {
if stateString == state.String() {
return state, nil
}
}
return appStateInvalid, fmt.Errorf("could not parse app state: %s", stateString)
}

57
vendor/github.com/status-im/status-go/api/backend.go generated vendored Normal file
View File

@@ -0,0 +1,57 @@
package api
import (
signercore "github.com/ethereum/go-ethereum/signer/core/apitypes"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/services/personal"
"github.com/status-im/status-go/services/typeddata"
"github.com/status-im/status-go/transactions"
)
// StatusBackend defines the contract for the Status.im service
type StatusBackend interface {
// IsNodeRunning() bool // NOTE: Only used in tests
StartNode(config *params.NodeConfig) error // NOTE: Only used in canary
StartNodeWithKey(acc multiaccounts.Account, password string, keyHex string, conf *params.NodeConfig) error
StartNodeWithAccount(acc multiaccounts.Account, password string, conf *params.NodeConfig) error
StartNodeWithAccountAndInitialConfig(account multiaccounts.Account, password string, settings settings.Settings, conf *params.NodeConfig, subaccs []*accounts.Account) error
StopNode() error
// RestartNode() error // NOTE: Only used in tests
GetNodeConfig() (*params.NodeConfig, error)
UpdateRootDataDir(datadir string)
// SelectAccount(loginParams account.LoginParams) error
OpenAccounts() error
GetAccounts() ([]multiaccounts.Account, error)
LocalPairingStarted() error
// SaveAccount(account multiaccounts.Account) error
SaveAccountAndStartNodeWithKey(acc multiaccounts.Account, password string, settings settings.Settings, conf *params.NodeConfig, subaccs []*accounts.Account, keyHex string) error
Recover(rpcParams personal.RecoverParams) (types.Address, error)
Logout() error
CallPrivateRPC(inputJSON string) (string, error)
CallRPC(inputJSON string) (string, error)
HashTransaction(sendArgs transactions.SendTxArgs) (transactions.SendTxArgs, types.Hash, error)
HashTypedData(typed typeddata.TypedData) (types.Hash, error)
HashTypedDataV4(typed signercore.TypedData) (types.Hash, error)
ResetChainData() error
SendTransaction(sendArgs transactions.SendTxArgs, password string) (hash types.Hash, err error)
SendTransactionWithChainID(chainID uint64, sendArgs transactions.SendTxArgs, password string) (hash types.Hash, err error)
SendTransactionWithSignature(sendArgs transactions.SendTxArgs, sig []byte) (hash types.Hash, err error)
SignHash(hexEncodedHash string) (string, error)
SignMessage(rpcParams personal.SignParams) (types.HexBytes, error)
SignTypedData(typed typeddata.TypedData, address string, password string) (types.HexBytes, error)
SignTypedDataV4(typed signercore.TypedData, address string, password string) (types.HexBytes, error)
ConnectionChange(typ string, expensive bool)
AppStateChange(state string)
ExtractGroupMembershipSignatures(signaturePairs [][2]string) ([]string, error)
SignGroupMembership(content string) (string, error)
}

View File

@@ -0,0 +1,258 @@
package api
import (
"strings"
"github.com/ethereum/go-ethereum/common"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/protocol/requests"
)
const (
mainnetChainID uint64 = 1
goerliChainID uint64 = 5
sepoliaChainID uint64 = 11155111
optimismChainID uint64 = 10
optimismGoerliChainID uint64 = 420
optimismSepoliaChainID uint64 = 11155420
arbitrumChainID uint64 = 42161
arbitrumGoerliChainID uint64 = 421613
arbitrumSepoliaChainID uint64 = 421614
sntSymbol = "SNT"
sttSymbol = "STT"
)
var ganacheTokenAddress = common.HexToAddress("0x8571Ddc46b10d31EF963aF49b6C7799Ea7eff818")
var mainnet = params.Network{
ChainID: mainnetChainID,
ChainName: "Ethereum Mainnet",
RPCURL: "https://eth-archival.rpc.grove.city/v1/",
FallbackURL: "https://mainnet.infura.io/v3/",
BlockExplorerURL: "https://etherscan.io/",
IconURL: "network/Network=Ethereum",
ChainColor: "#627EEA",
ShortName: "eth",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: false,
Layer: 1,
Enabled: true,
RelatedChainID: goerliChainID,
}
var goerli = params.Network{
ChainID: goerliChainID,
ChainName: "Ethereum Goerli",
RPCURL: "https://goerli-archival.rpc.grove.city/v1/",
FallbackURL: "https://goerli.infura.io/v3/",
BlockExplorerURL: "https://goerli.etherscan.io/",
IconURL: "network/Network=Testnet",
ChainColor: "#939BA1",
ShortName: "goEth",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: true,
Layer: 1,
Enabled: true,
RelatedChainID: mainnetChainID,
}
var sepolia = params.Network{
ChainID: sepoliaChainID,
ChainName: "Ethereum Sepolia",
RPCURL: "https://sepolia-archival.rpc.grove.city/v1/",
FallbackURL: "https://sepolia.infura.io/v3/",
BlockExplorerURL: "https://sepolia.etherscan.io/",
IconURL: "network/Network=Testnet",
ChainColor: "#51D0F0",
ShortName: "eth",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: true,
Layer: 1,
Enabled: true,
RelatedChainID: mainnetChainID,
}
var optimism = params.Network{
ChainID: optimismChainID,
ChainName: "Optimism",
RPCURL: "https://optimism-mainnet.rpc.grove.city/v1/",
FallbackURL: "https://optimism-mainnet.infura.io/v3/",
BlockExplorerURL: "https://optimistic.etherscan.io",
IconURL: "network/Network=Optimism",
ChainColor: "#E90101",
ShortName: "opt",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: false,
Layer: 2,
Enabled: true,
RelatedChainID: optimismGoerliChainID,
}
var optimismGoerli = params.Network{
ChainID: optimismGoerliChainID,
ChainName: "Optimism Goerli",
RPCURL: "https://optimism-goerli.infura.io/v3/",
FallbackURL: "",
BlockExplorerURL: "https://goerli-optimism.etherscan.io/",
IconURL: "network/Network=Testnet",
ChainColor: "#939BA1",
ShortName: "goOpt",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: true,
Layer: 2,
Enabled: false,
RelatedChainID: optimismChainID,
}
var optimismSepolia = params.Network{
ChainID: optimismSepoliaChainID,
ChainName: "Optimism Sepolia",
RPCURL: "https://optimism-sepolia.infura.io/v3/",
FallbackURL: "",
BlockExplorerURL: "https://sepolia-optimism.etherscan.io/",
IconURL: "network/Network=Testnet",
ChainColor: "#939BA1",
ShortName: "opt",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: true,
Layer: 2,
Enabled: false,
RelatedChainID: optimismChainID,
}
var arbitrum = params.Network{
ChainID: arbitrumChainID,
ChainName: "Arbitrum",
RPCURL: "https://arbitrum-one.rpc.grove.city/v1/",
FallbackURL: "https://arbitrum-mainnet.infura.io/v3/",
BlockExplorerURL: "https://arbiscan.io/",
IconURL: "network/Network=Arbitrum",
ChainColor: "#51D0F0",
ShortName: "arb",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: false,
Layer: 2,
Enabled: true,
RelatedChainID: arbitrumGoerliChainID,
}
var arbitrumGoerli = params.Network{
ChainID: arbitrumGoerliChainID,
ChainName: "Arbitrum Goerli",
RPCURL: "https://arbitrum-goerli.infura.io/v3/",
FallbackURL: "",
BlockExplorerURL: "https://goerli.arbiscan.io/",
IconURL: "network/Network=Testnet",
ChainColor: "#939BA1",
ShortName: "goArb",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: true,
Layer: 2,
Enabled: false,
RelatedChainID: arbitrumChainID,
}
var arbitrumSepolia = params.Network{
ChainID: arbitrumSepoliaChainID,
ChainName: "Arbitrum Sepolia",
RPCURL: "https://arbitrum-sepolia.infura.io/v3/",
FallbackURL: "",
BlockExplorerURL: "https://sepolia-explorer.arbitrum.io/",
IconURL: "network/Network=Testnet",
ChainColor: "#51D0F0",
ShortName: "arb",
NativeCurrencyName: "Ether",
NativeCurrencySymbol: "ETH",
NativeCurrencyDecimals: 18,
IsTest: true,
Layer: 2,
Enabled: false,
RelatedChainID: arbitrumChainID,
}
var defaultNetworks = []params.Network{
mainnet,
goerli,
sepolia,
optimism,
optimismGoerli,
optimismSepolia,
arbitrum,
arbitrumGoerli,
arbitrumSepolia,
}
var mainnetGanacheTokenOverrides = params.TokenOverride{
Symbol: sntSymbol,
Address: ganacheTokenAddress,
}
var goerliGanacheTokenOverrides = params.TokenOverride{
Symbol: sttSymbol,
Address: ganacheTokenAddress,
}
func setRPCs(networks []params.Network, request *requests.WalletSecretsConfig) []params.Network {
var networksWithRPC []params.Network
for _, n := range networks {
if request.InfuraToken != "" {
if strings.Contains(n.RPCURL, "infura") {
n.RPCURL += request.InfuraToken
}
if strings.Contains(n.FallbackURL, "infura") {
n.FallbackURL += request.InfuraToken
}
}
if request.PoktToken != "" {
if strings.Contains(n.RPCURL, "grove") {
n.RPCURL += request.PoktToken
}
if strings.Contains(n.FallbackURL, "grove") {
n.FallbackURL += request.PoktToken
}
}
if request.GanacheURL != "" {
n.RPCURL = request.GanacheURL
n.FallbackURL = request.GanacheURL
if n.ChainID == mainnetChainID {
n.TokenOverrides = []params.TokenOverride{
mainnetGanacheTokenOverrides,
}
} else if n.ChainID == goerliChainID {
n.TokenOverrides = []params.TokenOverride{
goerliGanacheTokenOverrides,
}
}
}
networksWithRPC = append(networksWithRPC, n)
}
return networksWithRPC
}
func BuildDefaultNetworks(request *requests.CreateAccount) []params.Network {
return setRPCs(defaultNetworks, &request.WalletSecretsConfig)
}

936
vendor/github.com/status-im/status-go/api/defaults.go generated vendored Normal file
View File

@@ -0,0 +1,936 @@
package api
import (
"crypto/rand"
"encoding/json"
"math/big"
"github.com/google/uuid"
"github.com/status-im/status-go/account/generator"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/protocol/identity/alias"
"github.com/status-im/status-go/protocol/requests"
)
const pathWalletRoot = "m/44'/60'/0'/0"
const pathEIP1581 = "m/43'/60'/1581'"
const pathDefaultChat = pathEIP1581 + "/0'/0"
const pathDefaultWallet = pathWalletRoot + "/0"
const defaultMnemonicLength = 12
const shardsTestClusterID = 16
const walletAccountDefaultName = "Account 1"
const keystoreRelativePath = "keystore"
const defaultKeycardPairingDataFile = "/ethereum/mainnet_rpc/keycard/pairings.json"
var paths = []string{pathWalletRoot, pathEIP1581, pathDefaultChat, pathDefaultWallet}
const (
statusProdFleet = "status.prod"
statusTestFleet = "status.test"
wakuv2ProdFleet = "wakuv2.prod"
wakuv2TestFleet = "wakuv2.test"
shardsTest = "shards.test"
)
var DefaultWakuNodes = map[string][]string{
statusProdFleet: []string{"enrtree://AL65EKLJAUXKKPG43HVTML5EFFWEZ7L4LOKTLZCLJASG4DSESQZEC@prod.status.nodes.status.im"},
statusTestFleet: []string{"enrtree://AIO6LUM3IVWCU2KCPBBI6FEH2W42IGK3ASCZHZGG5TIXUR56OGQUO@test.status.nodes.status.im"},
wakuv2ProdFleet: []string{"enrtree://ANEDLO25QVUGJOUTQFRYKWX6P4Z4GKVESBMHML7DZ6YK4LGS5FC5O@prod.wakuv2.nodes.status.im"},
wakuv2TestFleet: []string{"enrtree://AO47IDOLBKH72HIZZOXQP6NMRESAN7CHYWIBNXDXWRJRZWLODKII6@test.wakuv2.nodes.status.im"},
shardsTest: []string{"enrtree://AMOJVZX4V6EXP7NTJPMAYJYST2QP6AJXYW76IU6VGJS7UVSNDYZG4@boot.test.shards.nodes.status.im"},
}
var DefaultFleet = shardsTest
func defaultSettings(generatedAccountInfo generator.GeneratedAccountInfo, derivedAddresses map[string]generator.AccountInfo, mnemonic *string) (*settings.Settings, error) {
chatKeyString := derivedAddresses[pathDefaultChat].PublicKey
s := &settings.Settings{}
s.Mnemonic = &generatedAccountInfo.Mnemonic
s.BackupEnabled = true
logLevel := "INFO"
s.LogLevel = &logLevel
s.ProfilePicturesShowTo = settings.ProfilePicturesShowToEveryone
s.ProfilePicturesVisibility = settings.ProfilePicturesVisibilityEveryone
s.KeyUID = generatedAccountInfo.KeyUID
s.Address = types.HexToAddress(generatedAccountInfo.Address)
s.WalletRootAddress = types.HexToAddress(derivedAddresses[pathWalletRoot].Address)
s.URLUnfurlingMode = settings.URLUnfurlingAlwaysAsk
// Set chat key & name
name, err := alias.GenerateFromPublicKeyString(chatKeyString)
if err != nil {
return nil, err
}
s.Name = name
s.PublicKey = chatKeyString
s.DappsAddress = types.HexToAddress(derivedAddresses[pathDefaultWallet].Address)
s.EIP1581Address = types.HexToAddress(derivedAddresses[pathEIP1581].Address)
s.Mnemonic = mnemonic
signingPhrase, err := buildSigningPhrase()
if err != nil {
return nil, err
}
s.SigningPhrase = signingPhrase
s.SendPushNotifications = true
s.InstallationID = uuid.New().String()
s.UseMailservers = true
s.PreviewPrivacy = true
s.Currency = "usd"
s.LinkPreviewRequestEnabled = true
visibleTokens := make(map[string][]string)
visibleTokens["mainnet"] = []string{"SNT"}
visibleTokensJSON, err := json.Marshal(visibleTokens)
if err != nil {
return nil, err
}
visibleTokenJSONRaw := json.RawMessage(visibleTokensJSON)
s.WalletVisibleTokens = &visibleTokenJSONRaw
// TODO: fix this
networks := make([]map[string]string, 0)
networksJSON, err := json.Marshal(networks)
if err != nil {
return nil, err
}
networkRawMessage := json.RawMessage(networksJSON)
s.Networks = &networkRawMessage
s.CurrentNetwork = "mainnet_rpc"
s.TokenGroupByCommunity = false
s.ShowCommunityAssetWhenSendingTokens = true
s.DisplayAssetsBelowBalance = false
// NOTE 9 decimals of precision. Default value is translated to 0.1
s.DisplayAssetsBelowBalanceThreshold = 100000000
return s, nil
}
func SetDefaultFleet(nodeConfig *params.NodeConfig) error {
return SetFleet(DefaultFleet, nodeConfig)
}
func SetFleet(fleet string, nodeConfig *params.NodeConfig) error {
nodeConfig.WakuV2Config = params.WakuV2Config{
Enabled: true,
EnableDiscV5: true,
DiscoveryLimit: 20,
Host: "0.0.0.0",
AutoUpdate: true,
PeerExchange: true,
}
clusterConfig, err := params.LoadClusterConfigFromFleet(fleet)
if err != nil {
return err
}
nodeConfig.ClusterConfig = *clusterConfig
nodeConfig.ClusterConfig.Fleet = fleet
nodeConfig.ClusterConfig.WakuNodes = DefaultWakuNodes[fleet]
nodeConfig.ClusterConfig.DiscV5BootstrapNodes = DefaultWakuNodes[fleet]
if fleet == shardsTest {
nodeConfig.ClusterConfig.ClusterID = shardsTestClusterID
nodeConfig.WakuV2Config.UseShardAsDefaultTopic = true
}
return nil
}
func buildWalletConfig(request *requests.WalletSecretsConfig) params.WalletConfig {
walletConfig := params.WalletConfig{
Enabled: true,
AlchemyAPIKeys: make(map[uint64]string),
}
if request.OpenseaAPIKey != "" {
walletConfig.OpenseaAPIKey = request.OpenseaAPIKey
}
if request.RaribleMainnetAPIKey != "" {
walletConfig.RaribleMainnetAPIKey = request.RaribleMainnetAPIKey
}
if request.RaribleTestnetAPIKey != "" {
walletConfig.RaribleTestnetAPIKey = request.RaribleTestnetAPIKey
}
if request.InfuraToken != "" {
walletConfig.InfuraAPIKey = request.InfuraToken
}
if request.InfuraSecret != "" {
walletConfig.InfuraAPIKeySecret = request.InfuraSecret
}
if request.AlchemyEthereumMainnetToken != "" {
walletConfig.AlchemyAPIKeys[mainnetChainID] = request.AlchemyEthereumMainnetToken
}
if request.AlchemyEthereumGoerliToken != "" {
walletConfig.AlchemyAPIKeys[goerliChainID] = request.AlchemyEthereumGoerliToken
}
if request.AlchemyEthereumSepoliaToken != "" {
walletConfig.AlchemyAPIKeys[sepoliaChainID] = request.AlchemyEthereumSepoliaToken
}
if request.AlchemyArbitrumMainnetToken != "" {
walletConfig.AlchemyAPIKeys[arbitrumChainID] = request.AlchemyArbitrumMainnetToken
}
if request.AlchemyArbitrumGoerliToken != "" {
walletConfig.AlchemyAPIKeys[arbitrumGoerliChainID] = request.AlchemyArbitrumGoerliToken
}
if request.AlchemyArbitrumSepoliaToken != "" {
walletConfig.AlchemyAPIKeys[arbitrumSepoliaChainID] = request.AlchemyArbitrumSepoliaToken
}
if request.AlchemyOptimismMainnetToken != "" {
walletConfig.AlchemyAPIKeys[optimismChainID] = request.AlchemyOptimismMainnetToken
}
if request.AlchemyOptimismGoerliToken != "" {
walletConfig.AlchemyAPIKeys[optimismGoerliChainID] = request.AlchemyOptimismGoerliToken
}
if request.AlchemyOptimismSepoliaToken != "" {
walletConfig.AlchemyAPIKeys[optimismSepoliaChainID] = request.AlchemyOptimismSepoliaToken
}
return walletConfig
}
func defaultNodeConfig(installationID string, request *requests.CreateAccount) (*params.NodeConfig, error) {
// Set mainnet
nodeConfig := &params.NodeConfig{}
nodeConfig.NetworkID = request.NetworkID
nodeConfig.LogEnabled = request.LogEnabled
nodeConfig.LogFile = "geth.log"
nodeConfig.LogDir = request.LogFilePath
nodeConfig.LogLevel = "ERROR"
nodeConfig.DataDir = "/ethereum/mainnet_rpc"
nodeConfig.KeycardPairingDataFile = defaultKeycardPairingDataFile
if request.LogLevel != nil {
nodeConfig.LogLevel = *request.LogLevel
}
if request.UpstreamConfig != "" {
nodeConfig.UpstreamConfig = params.UpstreamRPCConfig{
Enabled: true,
URL: request.UpstreamConfig,
}
}
nodeConfig.Name = "StatusIM"
nodeConfig.Rendezvous = false
nodeConfig.NoDiscovery = true
nodeConfig.MaxPeers = 20
nodeConfig.MaxPendingPeers = 20
nodeConfig.WalletConfig = buildWalletConfig(&request.WalletSecretsConfig)
nodeConfig.LocalNotificationsConfig = params.LocalNotificationsConfig{Enabled: true}
nodeConfig.BrowsersConfig = params.BrowsersConfig{Enabled: true}
nodeConfig.PermissionsConfig = params.PermissionsConfig{Enabled: true}
nodeConfig.MailserversConfig = params.MailserversConfig{Enabled: true}
nodeConfig.ListenAddr = ":0"
err := SetDefaultFleet(nodeConfig)
if err != nil {
return nil, err
}
if request.WakuV2LightClient {
nodeConfig.WakuV2Config.LightClient = true
}
if request.WakuV2Nameserver != nil {
nodeConfig.WakuV2Config.Nameserver = *request.WakuV2Nameserver
}
nodeConfig.ShhextConfig = params.ShhextConfig{
BackupDisabledDataDir: request.BackupDisabledDataDir,
InstallationID: installationID,
MaxMessageDeliveryAttempts: 6,
MailServerConfirmations: true,
VerifyTransactionChainID: 1,
DataSyncEnabled: true,
PFSEnabled: true,
}
if request.VerifyTransactionURL != nil {
nodeConfig.ShhextConfig.VerifyTransactionURL = *request.VerifyTransactionURL
}
if request.VerifyENSURL != nil {
nodeConfig.ShhextConfig.VerifyENSURL = *request.VerifyENSURL
}
if request.VerifyTransactionChainID != nil {
nodeConfig.ShhextConfig.VerifyTransactionChainID = *request.VerifyTransactionChainID
}
if request.VerifyENSContractAddress != nil {
nodeConfig.ShhextConfig.VerifyENSContractAddress = *request.VerifyENSContractAddress
}
if request.LogLevel != nil {
nodeConfig.LogLevel = *request.LogLevel
nodeConfig.LogEnabled = true
} else {
nodeConfig.LogEnabled = false
}
nodeConfig.Networks = BuildDefaultNetworks(request)
return nodeConfig, nil
}
func buildSigningPhrase() (string, error) {
length := big.NewInt(int64(len(dictionary)))
a, err := rand.Int(rand.Reader, length)
if err != nil {
return "", err
}
b, err := rand.Int(rand.Reader, length)
if err != nil {
return "", err
}
c, err := rand.Int(rand.Reader, length)
if err != nil {
return "", err
}
return dictionary[a.Int64()] + " " + dictionary[b.Int64()] + " " + dictionary[c.Int64()], nil
}
var dictionary = []string{
"acid",
"alto",
"apse",
"arch",
"area",
"army",
"atom",
"aunt",
"babe",
"baby",
"back",
"bail",
"bait",
"bake",
"ball",
"band",
"bank",
"barn",
"base",
"bass",
"bath",
"bead",
"beak",
"beam",
"bean",
"bear",
"beat",
"beef",
"beer",
"beet",
"bell",
"belt",
"bend",
"bike",
"bill",
"bird",
"bite",
"blow",
"blue",
"boar",
"boat",
"body",
"bolt",
"bomb",
"bone",
"book",
"boot",
"bore",
"boss",
"bowl",
"brow",
"bulb",
"bull",
"burn",
"bush",
"bust",
"cafe",
"cake",
"calf",
"call",
"calm",
"camp",
"cane",
"cape",
"card",
"care",
"carp",
"cart",
"case",
"cash",
"cast",
"cave",
"cell",
"cent",
"chap",
"chef",
"chin",
"chip",
"chop",
"chub",
"chug",
"city",
"clam",
"clef",
"clip",
"club",
"clue",
"coal",
"coat",
"code",
"coil",
"coin",
"coke",
"cold",
"colt",
"comb",
"cone",
"cook",
"cope",
"copy",
"cord",
"cork",
"corn",
"cost",
"crab",
"craw",
"crew",
"crib",
"crop",
"crow",
"curl",
"cyst",
"dame",
"dare",
"dark",
"dart",
"dash",
"data",
"date",
"dead",
"deal",
"dear",
"debt",
"deck",
"deep",
"deer",
"desk",
"dhow",
"diet",
"dill",
"dime",
"dirt",
"dish",
"disk",
"dock",
"doll",
"door",
"dory",
"drag",
"draw",
"drop",
"drug",
"drum",
"duck",
"dump",
"dust",
"duty",
"ease",
"east",
"eave",
"eddy",
"edge",
"envy",
"epee",
"exam",
"exit",
"face",
"fact",
"fail",
"fall",
"fame",
"fang",
"farm",
"fawn",
"fear",
"feed",
"feel",
"feet",
"file",
"fill",
"film",
"find",
"fine",
"fire",
"fish",
"flag",
"flat",
"flax",
"flow",
"foam",
"fold",
"font",
"food",
"foot",
"fork",
"form",
"fort",
"fowl",
"frog",
"fuel",
"full",
"gain",
"gale",
"galn",
"game",
"garb",
"gate",
"gear",
"gene",
"gift",
"girl",
"give",
"glad",
"glen",
"glue",
"glut",
"goal",
"goat",
"gold",
"golf",
"gong",
"good",
"gown",
"grab",
"gram",
"gray",
"grey",
"grip",
"grit",
"gyro",
"hail",
"hair",
"half",
"hall",
"hand",
"hang",
"harm",
"harp",
"hate",
"hawk",
"head",
"heat",
"heel",
"hell",
"helo",
"help",
"hemp",
"herb",
"hide",
"high",
"hill",
"hire",
"hive",
"hold",
"hole",
"home",
"hood",
"hoof",
"hook",
"hope",
"hops",
"horn",
"hose",
"host",
"hour",
"hunt",
"hurt",
"icon",
"idea",
"inch",
"iris",
"iron",
"item",
"jail",
"jeep",
"jeff",
"joey",
"join",
"joke",
"judo",
"jump",
"junk",
"jury",
"jute",
"kale",
"keep",
"kick",
"kill",
"kilt",
"kind",
"king",
"kiss",
"kite",
"knee",
"knot",
"lace",
"lack",
"lady",
"lake",
"lamb",
"lamp",
"land",
"lark",
"lava",
"lawn",
"lead",
"leaf",
"leek",
"lier",
"life",
"lift",
"lily",
"limo",
"line",
"link",
"lion",
"lisa",
"list",
"load",
"loaf",
"loan",
"lock",
"loft",
"long",
"look",
"loss",
"lout",
"love",
"luck",
"lung",
"lute",
"lynx",
"lyre",
"maid",
"mail",
"main",
"make",
"male",
"mall",
"manx",
"many",
"mare",
"mark",
"mask",
"mass",
"mate",
"math",
"meal",
"meat",
"meet",
"menu",
"mess",
"mice",
"midi",
"mile",
"milk",
"mime",
"mind",
"mine",
"mini",
"mint",
"miss",
"mist",
"moat",
"mode",
"mole",
"mood",
"moon",
"most",
"moth",
"move",
"mule",
"mutt",
"nail",
"name",
"neat",
"neck",
"need",
"neon",
"nest",
"news",
"node",
"nose",
"note",
"oboe",
"okra",
"open",
"oval",
"oven",
"oxen",
"pace",
"pack",
"page",
"pail",
"pain",
"pair",
"palm",
"pard",
"park",
"part",
"pass",
"past",
"path",
"peak",
"pear",
"peen",
"peer",
"pelt",
"perp",
"pest",
"pick",
"pier",
"pike",
"pile",
"pimp",
"pine",
"ping",
"pink",
"pint",
"pipe",
"piss",
"pith",
"plan",
"play",
"plot",
"plow",
"poem",
"poet",
"pole",
"polo",
"pond",
"pony",
"poof",
"pool",
"port",
"post",
"prow",
"pull",
"puma",
"pump",
"pupa",
"push",
"quit",
"race",
"rack",
"raft",
"rage",
"rail",
"rain",
"rake",
"rank",
"rate",
"read",
"rear",
"reef",
"rent",
"rest",
"rice",
"rich",
"ride",
"ring",
"rise",
"risk",
"road",
"robe",
"rock",
"role",
"roll",
"roof",
"room",
"root",
"rope",
"rose",
"ruin",
"rule",
"rush",
"ruth",
"sack",
"safe",
"sage",
"sail",
"sale",
"salt",
"sand",
"sari",
"sash",
"save",
"scow",
"seal",
"seat",
"seed",
"self",
"sell",
"shed",
"shin",
"ship",
"shoe",
"shop",
"shot",
"show",
"sick",
"side",
"sign",
"silk",
"sill",
"silo",
"sing",
"sink",
"site",
"size",
"skin",
"sled",
"slip",
"smog",
"snob",
"snow",
"soap",
"sock",
"soda",
"sofa",
"soft",
"soil",
"song",
"soot",
"sort",
"soup",
"spot",
"spur",
"stag",
"star",
"stay",
"stem",
"step",
"stew",
"stop",
"stud",
"suck",
"suit",
"swan",
"swim",
"tail",
"tale",
"talk",
"tank",
"tard",
"task",
"taxi",
"team",
"tear",
"teen",
"tell",
"temp",
"tent",
"term",
"test",
"text",
"thaw",
"tile",
"till",
"time",
"tire",
"toad",
"toga",
"togs",
"tone",
"tool",
"toot",
"tote",
"tour",
"town",
"tram",
"tray",
"tree",
"trim",
"trip",
"tuba",
"tube",
"tuna",
"tune",
"turn",
"tutu",
"twig",
"type",
"unit",
"user",
"vane",
"vase",
"vast",
"veal",
"veil",
"vein",
"vest",
"vibe",
"view",
"vise",
"wait",
"wake",
"walk",
"wall",
"wash",
"wasp",
"wave",
"wear",
"weed",
"week",
"well",
"west",
"whip",
"wife",
"will",
"wind",
"wine",
"wing",
"wire",
"wish",
"wolf",
"wood",
"wool",
"word",
"work",
"worm",
"wrap",
"wren",
"yard",
"yarn",
"yawl",
"year",
"yoga",
"yoke",
"yurt",
"zinc",
"zone",
}

2484
vendor/github.com/status-im/status-go/api/geth_backend.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,248 @@
package multiformat
import (
"crypto/elliptic"
"errors"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
bls12381 "github.com/kilic/bls12-381"
"github.com/multiformats/go-multibase"
"github.com/multiformats/go-varint"
)
const (
secp256k1KeyType = 0xe7
bls12p381g1KeyType = 0xea
bls12p381g2KeyType = 0xeb
legacyKeyLength = 132
)
// SerializePublicKey serialises a non-serialised multibase encoded multicodec identified EC public key
// For details on usage see specs https://specs.status.im/spec/2#public-key-serialization
func SerializePublicKey(key, outputBase string) (string, error) {
dKey, err := multibaseDecode(key)
if err != nil {
return "", err
}
kt, i, err := getPublicKeyType(dKey)
if err != nil {
return "", err
}
cpk, err := compressPublicKey(dKey[i:], kt)
if err != nil {
return "", err
}
cpk = prependKeyIdentifier(cpk, kt, i)
return multibaseEncode(outputBase, cpk)
}
// DeserializePublicKey deserialise a serialised multibase encoded multicodec identified EC public key
// For details on usage see specs https://specs.status.im/spec/2#public-key-serialization
func DeserializePublicKey(key, outputBase string) (string, error) {
cpk, err := multibaseDecode(key)
if err != nil {
return "", err
}
kt, i, err := getPublicKeyType(cpk)
if err != nil {
return "", err
}
pk, err := decompressPublicKey(cpk[i:], kt)
if err != nil {
return "", err
}
pk = prependKeyIdentifier(pk, kt, i)
return multibaseEncode(outputBase, pk)
}
// SerializeLegacyKey converts a secp251k1 uncompressed key to
// a base58 compressed key
func SerializeLegacyKey(key string) (string, error) {
if len(key) != legacyKeyLength {
return "", errors.New("invalid key length")
}
keyWithPrefix := fmt.Sprintf("0x%x01%s", secp256k1KeyType, key[2:])
return SerializePublicKey(keyWithPrefix, "z")
}
// DeserializeCompressedKey converts a base58 compressed key to
// a secp251k1 uncompressed key
func DeserializeCompressedKey(key string) (string, error) {
if len(key) == 0 {
return "", errors.New("invalid key length")
}
deserialisedKey, err := DeserializePublicKey(key, "f")
if err != nil {
return "", err
}
return "0x" + deserialisedKey[5:], nil
}
// getPublicKeyType wrapper for the `varint.FromUvarint()` func
func getPublicKeyType(key []byte) (uint64, int, error) {
return varint.FromUvarint(key)
}
// prependKeyIdentifier prepends an Unsigned Variable Integer (uvarint) to a given []byte
func prependKeyIdentifier(key []byte, kt uint64, ktl int) []byte {
buf := make([]byte, ktl)
varint.PutUvarint(buf, kt)
key = append(buf, key...)
return key
}
// compressPublicKey serves as logic switch function to parse key data for compression based on the given keyType
func compressPublicKey(key []byte, keyType uint64) ([]byte, error) {
switch keyType {
case secp256k1KeyType:
return compressSecp256k1PublicKey(key)
case bls12p381g1KeyType:
return compressBls12p381g1PublicKey(key)
case bls12p381g2KeyType:
return compressBls12p381g2PublicKey(key)
default:
return nil, fmt.Errorf("unsupported public key type '%X'", keyType)
}
}
// compressSecp256k1PublicKey is a dedicated key compression function for secp256k1 pks
func compressSecp256k1PublicKey(key []byte) ([]byte, error) {
x, y := elliptic.Unmarshal(secp256k1.S256(), key)
if err := isSecp256k1XYValid(key, x, y); err != nil {
return nil, err
}
cpk := secp256k1.CompressPubkey(x, y)
return cpk, nil
}
// compressBls12p381g1PublicKey is a dedicated key compression function for bls12 381 g1 pks
func compressBls12p381g1PublicKey(key []byte) ([]byte, error) {
g1 := bls12381.NewG1()
// Generate the G1 point
pg1, err := g1.FromBytes(key)
if err != nil {
return nil, err
}
cpk := g1.ToCompressed(pg1)
return cpk, nil
}
// compressBls12p381g1PublicKey is a dedicated key compression function for bls12 381 g2 pks
func compressBls12p381g2PublicKey(key []byte) ([]byte, error) {
g2 := bls12381.NewG2()
// Generate the G2 point
pg2, err := g2.FromBytes(key)
if err != nil {
return nil, err
}
cpk := g2.ToCompressed(pg2)
return cpk, nil
}
// decompressPublicKey serves as logic switch function to parse key data for decompression based on the given keyType
func decompressPublicKey(key []byte, keyType uint64) ([]byte, error) {
switch keyType {
case secp256k1KeyType:
return decompressSecp256k1PublicKey(key)
case bls12p381g1KeyType:
return decompressBls12p381g1PublicKey(key)
case bls12p381g2KeyType:
return decompressBls12p381g2PublicKey(key)
default:
return nil, fmt.Errorf("unsupported public key type '%X'", keyType)
}
}
// decompressSecp256k1PublicKey is a dedicated key decompression function for secp256k1 pks
func decompressSecp256k1PublicKey(key []byte) ([]byte, error) {
x, y := secp256k1.DecompressPubkey(key)
if err := isSecp256k1XYValid(key, x, y); err != nil {
return nil, err
}
k := elliptic.Marshal(secp256k1.S256(), x, y)
return k, nil
}
// isSecp256k1XYValid checks if a given x and y coordinate is nil, returns an error if either x or y is nil
// secp256k1.DecompressPubkey will not return an error if a compressed pk fails decompression and instead returns
// nil x, y coordinates
func isSecp256k1XYValid(key []byte, x, y *big.Int) error {
if x == nil || y == nil {
return fmt.Errorf("invalid public key format, '%b'", key)
}
return nil
}
// decompressBls12p381g1PublicKey is a dedicated key decompression function for bls12 381 g1 pks
func decompressBls12p381g1PublicKey(key []byte) ([]byte, error) {
g1 := bls12381.NewG1()
pg1, err := g1.FromCompressed(key)
if err != nil {
return nil, err
}
pk := g1.ToUncompressed(pg1)
return pk, nil
}
// decompressBls12p381g2PublicKey is a dedicated key decompression function for bls12 381 g2 pks
func decompressBls12p381g2PublicKey(key []byte) ([]byte, error) {
g2 := bls12381.NewG2()
pg2, err := g2.FromCompressed(key)
if err != nil {
return nil, err
}
pk := g2.ToUncompressed(pg2)
return pk, nil
}
// multibaseEncode wraps `multibase.Encode()` extending the base functionality to support `0x` prefixed strings
func multibaseEncode(base string, data []byte) (string, error) {
if base == "0x" {
base = "f"
}
return multibase.Encode(multibase.Encoding(base[0]), data)
}
// multibaseDecode wraps `multibase.Decode()` extending the base functionality to support `0x` prefixed strings
func multibaseDecode(data string) ([]byte, error) {
if data[0:2] == "0x" {
data = "f" + data[2:]
}
_, dd, err := multibase.Decode(data)
return dd, err
}

View File

@@ -0,0 +1,101 @@
package api
import (
"encoding/json"
"path/filepath"
"testing"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/multiaccounts/settings"
"github.com/status-im/status-go/params"
"github.com/stretchr/testify/require"
)
func setupWalletTest(t *testing.T, password string) (backend *GethStatusBackend, defersFunc func(), err error) {
tmpdir := t.TempDir()
defers := make([]func(), 0)
defersFunc = func() {
for _, f := range defers {
f()
}
}
if err != nil {
return
}
backend = NewGethStatusBackend()
backend.UpdateRootDataDir(tmpdir)
err = backend.AccountManager().InitKeystore(filepath.Join(tmpdir, "keystore"))
if err != nil {
return
}
// Create master account
const pathWalletRoot = "m/44'/60'/0'/0"
accs, err := backend.AccountManager().
AccountsGenerator().
GenerateAndDeriveAddresses(12, 1, "", []string{pathWalletRoot})
if err != nil {
return
}
masterAccInfo := accs[0]
_, err = backend.AccountManager().AccountsGenerator().StoreDerivedAccounts(masterAccInfo.ID, password, []string{pathWalletRoot})
if err != nil {
return
}
account := multiaccounts.Account{
Name: "foo",
Timestamp: 1,
KeycardPairing: "pairing",
KeyUID: masterAccInfo.KeyUID,
}
err = backend.ensureDBsOpened(account, password)
require.NoError(t, err)
walletRootAddress := masterAccInfo.Derived[pathWalletRoot].Address
config, err := params.NewNodeConfig(tmpdir, 178733)
require.NoError(t, err)
networks := json.RawMessage("{}")
s := settings.Settings{
Address: types.HexToAddress(walletRootAddress),
DisplayName: "UserDisplayName",
CurrentNetwork: "mainnet_rpc",
DappsAddress: types.HexToAddress(walletRootAddress),
EIP1581Address: types.HexToAddress(walletRootAddress),
InstallationID: "d3efcff6-cffa-560e-a547-21d3858cbc51",
KeyUID: account.KeyUID,
LatestDerivedPath: 0,
Name: "Jittery Cornflowerblue Kingbird",
Networks: &networks,
PhotoPath: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAAjklEQVR4nOzXwQmFMBAAUZXUYh32ZB32ZB02sxYQQSZGsod55/91WFgSS0RM+SyjA56ZRZhFmEWYRRT6h+M6G16zrxv6fdJpmUWYRbxsYr13dKfanpN0WmYRZhGzXz6AWYRZRIfbaX26fT9Jk07LLMIsosPt9I/dTDotswizCG+nhFmEWYRZhFnEHQAA///z1CFkYamgfQAAAABJRU5ErkJggg==",
PreviewPrivacy: false,
PublicKey: masterAccInfo.PublicKey,
SigningPhrase: "yurt joey vibe",
WalletRootAddress: types.HexToAddress(walletRootAddress)}
err = backend.saveAccountsAndSettings(s, config, nil)
require.Error(t, err)
require.True(t, err == accounts.ErrKeypairWithoutAccounts)
// this is for StatusNode().Config() call inside of the getVerifiedWalletAccount
err = backend.StartNode(config)
require.NoError(t, err)
defers = append(defers, func() {
require.NoError(t, backend.StopNode())
})
return
}

61
vendor/github.com/status-im/status-go/api/utils.go generated vendored Normal file
View File

@@ -0,0 +1,61 @@
package api
import (
"bytes"
"encoding/hex"
"strconv"
"strings"
"github.com/status-im/status-go/eth-node/crypto"
)
// RunAsync runs the specified function asynchronously.
func RunAsync(f func() error) <-chan error {
resp := make(chan error, 1)
go func() {
err := f()
resp <- err
close(resp)
}()
return resp
}
// HashMessage calculates the hash of a message to be safely signed by the keycard
// The hash is calulcated as
//
// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}).
//
// This gives context to the signed message and prevents signing of transactions.
func HashMessage(message string) ([]byte, error) {
buf := bytes.NewBufferString("\x19Ethereum Signed Message:\n")
if value, ok := decodeHexStrict(message); ok {
if _, err := buf.WriteString(strconv.Itoa(len(value))); err != nil {
return nil, err
}
if _, err := buf.Write(value); err != nil {
return nil, err
}
} else {
if _, err := buf.WriteString(strconv.Itoa(len(message))); err != nil {
return nil, err
}
if _, err := buf.WriteString(message); err != nil {
return nil, err
}
}
return crypto.Keccak256(buf.Bytes()), nil
}
func decodeHexStrict(s string) ([]byte, bool) {
if !strings.HasPrefix(s, "0x") {
return nil, false
}
value, err := hex.DecodeString(s[2:])
if err != nil {
return nil, false
}
return value, true
}

View File

@@ -0,0 +1,449 @@
package appdatabase
import (
"database/sql"
"encoding/json"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/appdatabase/migrations"
migrationsprevnodecfg "github.com/status-im/status-go/appdatabase/migrationsprevnodecfg"
"github.com/status-im/status-go/nodecfg"
"github.com/status-im/status-go/services/wallet/bigint"
w_common "github.com/status-im/status-go/services/wallet/common"
"github.com/status-im/status-go/sqlite"
)
const nodeCfgMigrationDate = 1640111208
var customSteps = []*sqlite.PostStep{
{Version: 1674136690, CustomMigration: migrateEnsUsernames},
{Version: 1686048341, CustomMigration: migrateWalletJSONBlobs, RollBackVersion: 1686041510},
{Version: 1687193315, CustomMigration: migrateWalletTransferFromToAddresses, RollBackVersion: 1686825075},
}
type DbInitializer struct {
}
func (a DbInitializer) Initialize(path, password string, kdfIterationsNumber int) (*sql.DB, error) {
return InitializeDB(path, password, kdfIterationsNumber)
}
func doMigration(db *sql.DB) error {
lastMigration, migrationTableExists, err := sqlite.GetLastMigrationVersion(db)
if err != nil {
return err
}
if !migrationTableExists || (lastMigration > 0 && lastMigration < nodeCfgMigrationDate) {
// If it's the first time migration's being run, or latest migration happened before migrating the nodecfg table
err = migrationsprevnodecfg.Migrate(db)
if err != nil {
return err
}
// NodeConfig migration cannot be done with SQL
err = nodecfg.MigrateNodeConfig(db)
if err != nil {
return err
}
}
// Run all the new migrations
err = migrations.Migrate(db, customSteps)
if err != nil {
return err
}
return nil
}
// InitializeDB creates db file at a given path and applies migrations.
func InitializeDB(path, password string, kdfIterationsNumber int) (*sql.DB, error) {
db, err := sqlite.OpenDB(path, password, kdfIterationsNumber)
if err != nil {
return nil, err
}
err = doMigration(db)
if err != nil {
return nil, err
}
return db, nil
}
func migrateEnsUsernames(sqlTx *sql.Tx) error {
// 1. Check if ens_usernames table already exist
// row := sqlTx.QueryRow("SELECT exists(SELECT name FROM sqlite_master WHERE type='table' AND name='ens_usernames')")
// tableExists := false
// err := row.Scan(&tableExists)
// if err != nil && err != sql.ErrNoRows {
// return err
// }
// if tableExists {
// return nil
// }
// -- 1. Create new ens_usernames table
// _, err = sqlTx.Exec(`CREATE TABLE IF NOT EXISTS ens_usernames (
// "username" TEXT NOT NULL,
// "chain_id" UNSIGNED BIGINT DEFAULT 1);`)
// if err != nil {
// log.Error("Migrating ens usernames: failed to create table", "err", err.Error())
// return err
// }
// -- 2. Move current `settings.usernames` to the new table
/*
INSERT INTO ens_usernames (username)
SELECT json_each.value FROM settings, json_each(usernames);
*/
rows, err := sqlTx.Query(`SELECT usernames FROM settings`)
if err != nil {
log.Error("Migrating ens usernames: failed to query 'settings.usernames'", "err", err.Error())
return err
}
defer rows.Close()
var usernames []string
for rows.Next() {
var usernamesJSON sql.NullString
err := rows.Scan(&usernamesJSON)
if err != nil {
return err
}
if !usernamesJSON.Valid {
continue
}
var list []string
err = json.Unmarshal([]byte(usernamesJSON.String), &list)
if err != nil {
return err
}
usernames = append(usernames, list...)
}
defaultChainID := 1
for _, username := range usernames {
var usernameAlreadyMigrated bool
row := sqlTx.QueryRow(`SELECT EXISTS(SELECT 1 FROM ens_usernames WHERE username=? AND chain_id=?)`, username, defaultChainID)
err := row.Scan(&usernameAlreadyMigrated)
if err != nil {
return err
}
if usernameAlreadyMigrated {
continue
}
_, err = sqlTx.Exec(`INSERT INTO ens_usernames (username, chain_id) VALUES (?, ?)`, username, defaultChainID)
if err != nil {
log.Error("Migrating ens usernames: failed to insert username into new database", "ensUsername", username, "err", err.Error())
}
}
return nil
}
func MigrateV3ToV4(v3Path string, v4Path string, password string, kdfIterationsNumber int, onStart func(), onEnd func()) error {
return sqlite.MigrateV3ToV4(v3Path, v4Path, password, kdfIterationsNumber, onStart, onEnd)
}
const (
batchSize = 1000
)
func migrateWalletJSONBlobs(sqlTx *sql.Tx) error {
var batchEntries [][]interface{}
// Extract useful information from the receipt blob and store it as sql interpretable
//
// Added tx_hash because the hash column in the transfers table is not (always) the transaction hash.
// Each entry in that table could either be: A native token (ETH) transfer or ERC20/ERC721 token transfer
// Added block_hash because the block_hash we have is generated by us and used as block entry ID
// Added receipt_type, the type we have only indicates if chain or token
// Added log_index that the log data represents
//
// Dropped storing postState because it was replaced by the status after EIP 658
// Dropped duplicating logs until we have a more structured way to store them.
// They can be extracted from the transfers.receipt still
// Dropped the bloom filter because in SQLite is not possible to use it in an
// efficient manner
//
// Extract useful information from the tx blob
//
// Added tx_type, which might be different than the receipt type
//
// Dropped access_list, need a separate table for it
// Already there chain_id
// Dropped v, r, s because I see no way to be useful as BLOBs
// Added BIGINT values as clamped 64 INT because we can't use 128 bits blobs/strings for int arithmetics
// _clamped64 prefix indicate clamped 64 bits INT values might be useful for queries (sorting, filtering ...)
// The amount is stored as a fixed length 128 bit hex string, in
// order to be able to sort and filter by it
newColumnsAndIndexSetup := `
ALTER TABLE transfers ADD COLUMN status INT;
ALTER TABLE transfers ADD COLUMN receipt_type INT;
ALTER TABLE transfers ADD COLUMN tx_hash BLOB;
ALTER TABLE transfers ADD COLUMN log_index INT;
ALTER TABLE transfers ADD COLUMN block_hash BLOB;
ALTER TABLE transfers ADD COLUMN cumulative_gas_used INT;
ALTER TABLE transfers ADD COLUMN contract_address TEXT;
ALTER TABLE transfers ADD COLUMN gas_used INT;
ALTER TABLE transfers ADD COLUMN tx_index INT;
ALTER TABLE transfers ADD COLUMN tx_type INT;
ALTER TABLE transfers ADD COLUMN protected BOOLEAN;
ALTER TABLE transfers ADD COLUMN gas_limit UNSIGNED INT;
ALTER TABLE transfers ADD COLUMN gas_price_clamped64 INT;
ALTER TABLE transfers ADD COLUMN gas_tip_cap_clamped64 INT;
ALTER TABLE transfers ADD COLUMN gas_fee_cap_clamped64 INT;
ALTER TABLE transfers ADD COLUMN amount_padded128hex CHAR(32);
ALTER TABLE transfers ADD COLUMN account_nonce INT;
ALTER TABLE transfers ADD COLUMN size INT;
ALTER TABLE transfers ADD COLUMN token_address BLOB;
ALTER TABLE transfers ADD COLUMN token_id BLOB;
CREATE INDEX idx_transfers_filter ON transfers (status, token_address, token_id);`
rowIndex := 0
mightHaveRows := true
_, err := sqlTx.Exec(newColumnsAndIndexSetup)
if err != nil {
return err
}
for mightHaveRows {
var chainID uint64
var hash common.Hash
var address common.Address
var entryType string
rows, err := sqlTx.Query(`SELECT hash, address, network_id, tx, receipt, log, type FROM transfers WHERE tx IS NOT NULL OR receipt IS NOT NULL LIMIT ? OFFSET ?`, batchSize, rowIndex)
if err != nil {
return err
}
curProcessed := 0
for rows.Next() {
tx := &types.Transaction{}
r := &types.Receipt{}
l := &types.Log{}
// Scan row data into the transaction and receipt objects
nullableTx := sqlite.JSONBlob{Data: tx}
nullableR := sqlite.JSONBlob{Data: r}
nullableL := sqlite.JSONBlob{Data: l}
err = rows.Scan(&hash, &address, &chainID, &nullableTx, &nullableR, &nullableL, &entryType)
if err != nil {
rows.Close()
return err
}
var logIndex *uint
if nullableL.Valid {
logIndex = new(uint)
*logIndex = l.Index
}
var currentRow []interface{}
// Check if the receipt is not null before transferring the receipt data
if nullableR.Valid {
currentRow = append(currentRow, r.Status, r.Type, r.TxHash, logIndex, r.BlockHash, r.CumulativeGasUsed, r.ContractAddress, r.GasUsed, r.TransactionIndex)
} else {
for i := 0; i < 9; i++ {
currentRow = append(currentRow, nil)
}
}
if nullableTx.Valid {
correctType, tokenID, value, tokenAddress := extractToken(entryType, tx, l, nullableL.Valid)
gasPrice := sqlite.BigIntToClampedInt64(tx.GasPrice())
gasTipCap := sqlite.BigIntToClampedInt64(tx.GasTipCap())
gasFeeCap := sqlite.BigIntToClampedInt64(tx.GasFeeCap())
valueStr := sqlite.BigIntToPadded128BitsStr(value)
currentRow = append(currentRow, tx.Type(), tx.Protected(), tx.Gas(), gasPrice, gasTipCap, gasFeeCap, valueStr, tx.Nonce(), int64(tx.Size()), tokenAddress, (*bigint.SQLBigIntBytes)(tokenID), correctType)
} else {
for i := 0; i < 11; i++ {
currentRow = append(currentRow, nil)
}
currentRow = append(currentRow, w_common.EthTransfer)
}
currentRow = append(currentRow, hash, address, chainID)
batchEntries = append(batchEntries, currentRow)
curProcessed++
}
rowIndex += curProcessed
// Check if there was an error in the last rows.Next()
rows.Close()
if err = rows.Err(); err != nil {
return err
}
mightHaveRows = (curProcessed == batchSize)
// insert extracted data into the new columns
if len(batchEntries) > 0 {
var stmt *sql.Stmt
stmt, err = sqlTx.Prepare(`UPDATE transfers SET status = ?, receipt_type = ?, tx_hash = ?, log_index = ?, block_hash = ?, cumulative_gas_used = ?, contract_address = ?, gas_used = ?, tx_index = ?,
tx_type = ?, protected = ?, gas_limit = ?, gas_price_clamped64 = ?, gas_tip_cap_clamped64 = ?, gas_fee_cap_clamped64 = ?, amount_padded128hex = ?, account_nonce = ?, size = ?, token_address = ?, token_id = ?, type = ?
WHERE hash = ? AND address = ? AND network_id = ?`)
if err != nil {
return err
}
for _, dataEntry := range batchEntries {
_, err = stmt.Exec(dataEntry...)
if err != nil {
return err
}
}
// Reset placeHolders and batchEntries for the next batch
batchEntries = [][]interface{}{}
}
}
return nil
}
func extractToken(entryType string, tx *types.Transaction, l *types.Log, logValid bool) (correctType w_common.Type, tokenID *big.Int, value *big.Int, tokenAddress *common.Address) {
if logValid {
correctType, tokenAddress, _, _ = w_common.ExtractTokenTransferData(w_common.Type(entryType), l, tx)
_, _, _, tokenIDs, values, _ := w_common.ParseTransferLog(*l)
if len(tokenIDs) > 0 {
tokenID = tokenIDs[0]
}
if len(values) > 0 {
value = values[0]
}
} else {
correctType = w_common.Type(entryType)
value = new(big.Int).Set(tx.Value())
}
return
}
func migrateWalletTransferFromToAddresses(sqlTx *sql.Tx) error {
var batchEntries [][]interface{}
// Extract transfer from/to addresses and add the information into the new columns
// Re-extract token address and insert it as blob instead of string
newColumnsAndIndexSetup := `
ALTER TABLE transfers ADD COLUMN tx_from_address BLOB;
ALTER TABLE transfers ADD COLUMN tx_to_address BLOB;`
rowIndex := 0
mightHaveRows := true
_, err := sqlTx.Exec(newColumnsAndIndexSetup)
if err != nil {
return err
}
for mightHaveRows {
var chainID uint64
var hash common.Hash
var address common.Address
var sender common.Address
var entryType string
rows, err := sqlTx.Query(`SELECT hash, address, sender, network_id, tx, log, type FROM transfers WHERE tx IS NOT NULL OR receipt IS NOT NULL LIMIT ? OFFSET ?`, batchSize, rowIndex)
if err != nil {
return err
}
curProcessed := 0
for rows.Next() {
tx := &types.Transaction{}
l := &types.Log{}
// Scan row data into the transaction and receipt objects
nullableTx := sqlite.JSONBlob{Data: tx}
nullableL := sqlite.JSONBlob{Data: l}
err = rows.Scan(&hash, &address, &sender, &chainID, &nullableTx, &nullableL, &entryType)
if err != nil {
rows.Close()
return err
}
var currentRow []interface{}
var tokenAddress *common.Address
var txFrom *common.Address
var txTo *common.Address
if nullableTx.Valid {
if nullableL.Valid {
_, tokenAddress, txFrom, txTo = w_common.ExtractTokenTransferData(w_common.Type(entryType), l, tx)
} else {
txFrom = &sender
txTo = tx.To()
}
}
currentRow = append(currentRow, tokenAddress, txFrom, txTo)
currentRow = append(currentRow, hash, address, chainID)
batchEntries = append(batchEntries, currentRow)
curProcessed++
}
rowIndex += curProcessed
// Check if there was an error in the last rows.Next()
rows.Close()
if err = rows.Err(); err != nil {
return err
}
mightHaveRows = (curProcessed == batchSize)
// insert extracted data into the new columns
if len(batchEntries) > 0 {
var stmt *sql.Stmt
stmt, err = sqlTx.Prepare(`UPDATE transfers SET token_address = ?, tx_from_address = ?, tx_to_address = ?
WHERE hash = ? AND address = ? AND network_id = ?`)
if err != nil {
return err
}
for _, dataEntry := range batchEntries {
_, err = stmt.Exec(dataEntry...)
if err != nil {
return err
}
}
// Reset placeHolders and batchEntries for the next batch
batchEntries = [][]interface{}{}
}
}
return nil
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,30 @@
package migrations
import (
"database/sql"
bindata "github.com/status-im/migrate/v4/source/go_bindata"
"github.com/status-im/status-go/sqlite"
)
// Migrate applies migrations.
// see Migrate in vendor/status-go/sqlite/migrate.go
func Migrate(db *sql.DB, customSteps []*sqlite.PostStep) error {
return sqlite.Migrate(db, bindata.Resource(
AssetNames(),
func(name string) ([]byte, error) {
return Asset(name)
},
), customSteps, nil)
}
// MigrateTo is used for testing purposes
func MigrateTo(db *sql.DB, customSteps []*sqlite.PostStep, untilVersion uint) error {
return sqlite.Migrate(db, bindata.Resource(
AssetNames(),
func(name string) ([]byte, error) {
return Asset(name)
},
), customSteps, &untilVersion)
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,19 @@
package migrationsprevnodecfg
import (
"database/sql"
bindata "github.com/status-im/migrate/v4/source/go_bindata"
"github.com/status-im/status-go/sqlite"
)
// Migrate applies migrations.
func Migrate(db *sql.DB) error {
return sqlite.Migrate(db, bindata.Resource(
AssetNames(),
func(name string) ([]byte, error) {
return Asset(name)
},
), nil, nil)
}

View File

@@ -0,0 +1,315 @@
package appmetrics
import (
"database/sql"
"encoding/json"
"errors"
"strings"
"time"
"github.com/xeipuuv/gojsonschema"
)
type AppMetricEventType string
// Value is `json.RawMessage` so we can send any json shape, including strings
// Validation is handled using JSON schemas defined in validators.go, instead of Golang structs
type AppMetric struct {
ID int `json:"-"`
MessageID string `json:"message_id"`
Event AppMetricEventType `json:"event"`
Value json.RawMessage `json:"value"`
AppVersion string `json:"app_version"`
OS string `json:"os"`
SessionID string `json:"session_id"`
CreatedAt time.Time `json:"created_at"`
Processed bool `json:"processed"`
ReceivedAt time.Time `json:"received_at"`
}
type AppMetricValidationError struct {
Metric AppMetric
Errors []gojsonschema.ResultError
}
type Page struct {
AppMetrics []AppMetric
TotalCount int
}
const (
// status-mobile navigation events
NavigateTo AppMetricEventType = "navigate-to"
ScreensOnWillFocus AppMetricEventType = "screens/on-will-focus"
)
// EventSchemaMap Every event should have a schema attached
var EventSchemaMap = map[AppMetricEventType]interface{}{
NavigateTo: NavigateToCofxSchema,
ScreensOnWillFocus: NavigateToCofxSchema,
}
func NewDB(db *sql.DB) *Database {
return &Database{db: db}
}
// Database sql wrapper for operations with browser objects.
type Database struct {
db *sql.DB
}
// Close closes database.
func (db Database) Close() error {
return db.db.Close()
}
func jsonschemaErrorsToError(validationErrors []AppMetricValidationError) error {
var fieldErrors []string
for _, appMetricValidationError := range validationErrors {
metric := appMetricValidationError.Metric
errors := appMetricValidationError.Errors
var errorDesc string = "Error in event: " + string(metric.Event) + " - "
for _, e := range errors {
errorDesc = errorDesc + "value." + e.Context().String() + ":" + e.Description()
}
fieldErrors = append(fieldErrors, errorDesc)
}
return errors.New(strings.Join(fieldErrors[:], "/ "))
}
func (db *Database) ValidateAppMetrics(appMetrics []AppMetric) (err error) {
var calculatedErrors []AppMetricValidationError
for _, metric := range appMetrics {
schema := EventSchemaMap[metric.Event]
if schema == nil {
return errors.New("No schema defined for: " + string(metric.Event))
}
schemaLoader := gojsonschema.NewGoLoader(schema)
valLoader := gojsonschema.NewStringLoader(string(metric.Value))
res, err := gojsonschema.Validate(schemaLoader, valLoader)
if err != nil {
return err
}
// validate all metrics and save errors
if !res.Valid() {
calculatedErrors = append(calculatedErrors, AppMetricValidationError{metric, res.Errors()})
}
}
if len(calculatedErrors) > 0 {
return jsonschemaErrorsToError(calculatedErrors)
}
return
}
func (db *Database) SaveAppMetrics(appMetrics []AppMetric, sessionID string) (err error) {
var (
tx *sql.Tx
insert *sql.Stmt
)
// make sure that the shape of the metric is same as expected
err = db.ValidateAppMetrics(appMetrics)
if err != nil {
return err
}
// start txn
tx, err = db.db.Begin()
if err != nil {
return err
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
_ = tx.Rollback()
}()
insert, err = tx.Prepare("INSERT INTO app_metrics (event, value, app_version, operating_system, session_id, processed) VALUES (?, ?, ?, ?, ?, ?)")
if err != nil {
return err
}
for _, metric := range appMetrics {
_, err = insert.Exec(metric.Event, metric.Value, metric.AppVersion, metric.OS, sessionID, metric.Processed)
if err != nil {
return
}
}
return
}
func (db *Database) GetAppMetrics(limit int, offset int) (page Page, err error) {
countErr := db.db.QueryRow("SELECT count(*) FROM app_metrics").Scan(&page.TotalCount)
if countErr != nil {
return page, countErr
}
rows, err := db.db.Query("SELECT id, event, value, app_version, operating_system, session_id, created_at, processed FROM app_metrics LIMIT ? OFFSET ?", limit, offset)
if err != nil {
return page, err
}
defer rows.Close()
page.AppMetrics, err = db.getFromRows(rows)
return page, err
}
func (db *Database) getFromRows(rows *sql.Rows) (appMetrics []AppMetric, err error) {
var metrics []AppMetric
for rows.Next() {
metric := AppMetric{}
err = rows.Scan(
&metric.ID,
&metric.Event,
&metric.Value,
&metric.AppVersion,
&metric.OS,
&metric.SessionID,
&metric.CreatedAt,
&metric.Processed,
)
if err != nil {
return metrics, err
}
metrics = append(metrics, metric)
}
return metrics, nil
}
func (db *Database) GetUnprocessed() ([]AppMetric, error) {
rows, err := db.db.Query("SELECT id, event, value, app_version, operating_system, session_id, created_at, processed FROM app_metrics WHERE processed IS ? ORDER BY session_id ASC, created_at ASC", false)
if err != nil {
return nil, err
}
defer rows.Close()
return db.getFromRows(rows)
}
func (db *Database) GetUnprocessedGroupedBySession() (map[string][]AppMetric, error) {
uam, err := db.GetUnprocessed()
if err != nil {
return nil, err
}
out := map[string][]AppMetric{}
for _, am := range uam {
out[am.SessionID] = append(out[am.SessionID], am)
}
return out, nil
}
func (db *Database) SetToProcessedByIDs(ids []int) (err error) {
var (
tx *sql.Tx
update *sql.Stmt
)
// start txn
tx, err = db.db.Begin()
if err != nil {
return err
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
_ = tx.Rollback()
}()
// Generate prepared statement IN list
in := "("
for i := 0; i < len(ids); i++ {
in += "?,"
}
in = in[:len(in)-1] + ")"
update, err = tx.Prepare("UPDATE app_metrics SET processed = 1 WHERE id IN " + in) // nolint: gosec
if err != nil {
return err
}
// Convert the ids into Stmt.Exec compatible variadic
args := make([]interface{}, 0, len(ids))
for _, id := range ids {
args = append(args, id)
}
_, err = update.Exec(args...)
if err != nil {
return
}
return
}
func (db *Database) SetToProcessed(appMetrics []AppMetric) (err error) {
ids := GetAppMetricsIDs(appMetrics)
return db.SetToProcessedByIDs(ids)
}
func (db *Database) GetMessagesOlderThan(date *time.Time) ([]AppMetric, error) {
rows, err := db.db.Query("SELECT id, event, value, app_version, operating_system, session_id, created_at, processed FROM app_metrics WHERE created_at < ?", date)
if err != nil {
return nil, err
}
defer rows.Close()
return db.getFromRows(rows)
}
func (db *Database) DeleteOlderThan(date *time.Time) (err error) {
var (
tx *sql.Tx
d *sql.Stmt
)
// start txn
tx, err = db.db.Begin()
if err != nil {
return err
}
defer func() {
if err == nil {
err = tx.Commit()
return
}
_ = tx.Rollback()
}()
d, err = tx.Prepare("DELETE FROM app_metrics WHERE created_at < ?")
if err != nil {
return err
}
_, err = d.Exec(date)
if err != nil {
return
}
return
}
func GetAppMetricsIDs(appMetrics []AppMetric) []int {
var ids []int
for _, am := range appMetrics {
ids = append(ids, am.ID)
}
return ids
}

View File

@@ -0,0 +1,21 @@
package appmetrics
import "encoding/json"
func GenerateMetrics(num int) []AppMetric {
var appMetrics []AppMetric
for i := 0; i < num; i++ {
am := AppMetric{
Event: NavigateTo,
Value: json.RawMessage(`{"view_id": "some-view-id", "params": {"screen": "login"}}`),
OS: "android",
AppVersion: "1.11",
}
if i < num/2 {
am.Processed = true
}
appMetrics = append(appMetrics, am)
}
return appMetrics
}

View File

@@ -0,0 +1,24 @@
package appmetrics
var NavigateToCofxSchema = map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"view_id": map[string]interface{}{
"type": "string",
"maxLength": 32,
},
"params": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"screen": map[string]interface{}{
"type": "string",
"maxLength": 32,
},
},
"additionalProperties": false,
"required": []string{"screen"},
},
},
"additionalProperties": false,
"required": []string{"view_id", "params"},
}

View File

@@ -0,0 +1,53 @@
package dbsetup
import (
"database/sql"
"errors"
"github.com/ethereum/go-ethereum/log"
)
const InMemoryPath = ":memory:"
// The reduced number of kdf iterations (for performance reasons) which is
// currently used for derivation of the database key
// https://github.com/status-im/status-go/pull/1343
// https://notes.status.im/i8Y_l7ccTiOYq09HVgoFwA
const ReducedKDFIterationsNumber = 3200
type DatabaseInitializer interface {
Initialize(path, password string, kdfIterationsNumber int) (*sql.DB, error)
}
// GetDBFilename takes an instance of sql.DB and returns the filename of the "main" database
func GetDBFilename(db *sql.DB) (string, error) {
if db == nil {
logger := log.New()
logger.Warn("GetDBFilename was passed a nil pointer sql.DB")
return "", nil
}
var i, category, filename string
rows, err := db.Query("PRAGMA database_list;")
if err != nil {
return "", err
}
defer rows.Close()
for rows.Next() {
err = rows.Scan(&i, &category, &filename)
if err != nil {
return "", err
}
// The "main" database is the one we care about
if category == "main" {
return filename, nil
}
}
if err := rows.Err(); err != nil {
return "", err
}
return "", errors.New("no main database found")
}

View File

@@ -0,0 +1,12 @@
package common
import "runtime"
const (
AndroidPlatform = "android"
WindowsPlatform = "windows"
)
func OperatingSystemIs(targetOS string) bool {
return runtime.GOOS == targetOS
}

View File

@@ -0,0 +1,13 @@
package common
import (
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/rpc"
)
type StatusService interface {
Start() error
Stop() error
Protocols() []p2p.Protocol
APIs() []rpc.API
}

24
vendor/github.com/status-im/status-go/common/utils.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
package common
import (
"crypto/ecdsa"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/protocol/protobuf"
)
func RecoverKey(m *protobuf.ApplicationMetadataMessage) (*ecdsa.PublicKey, error) {
if m.Signature == nil {
return nil, nil
}
recoveredKey, err := crypto.SigToPub(
crypto.Keccak256(m.Payload),
m.Signature,
)
if err != nil {
return nil, err
}
return recoveredKey, nil
}

View File

@@ -0,0 +1,76 @@
package connection
import (
"fmt"
)
// State represents device connection state and type,
// as reported by mobile framework.
//
// Zero value represents default assumption about network (online and unknown type).
type State struct {
Offline bool `json:"offline"`
Type Type `json:"type"`
Expensive bool `json:"expensive"`
}
// Type represents description of available
// connection types as reported by React Native (see
// https://facebook.github.io/react-native/docs/netinfo.html)
// We're interested mainly in 'wifi' and 'cellular', but
// other types are also may be used.
type Type byte
const (
Offline = "offline"
Wifi = "wifi"
Cellular = "cellular"
Unknown = "unknown"
None = "none"
)
// NewType creates new Type from string.
func NewType(s string) Type {
switch s {
case Cellular:
return connectionCellular
case Wifi:
return connectionWifi
}
return connectionUnknown
}
// Type constants
const (
connectionUnknown Type = iota
connectionCellular // cellular, LTE, 4G, 3G, EDGE, etc.
connectionWifi // WIFI or iOS simulator
)
func (c State) IsExpensive() bool {
return c.Expensive || c.Type == connectionCellular
}
// string formats ConnectionState for logs. Implements Stringer.
func (c State) String() string {
if c.Offline {
return Offline
}
var typ string
switch c.Type {
case connectionWifi:
typ = Wifi
case connectionCellular:
typ = Cellular
default:
typ = Unknown
}
if c.Expensive {
return fmt.Sprintf("%s (expensive)", typ)
}
return typ
}

View File

@@ -0,0 +1,275 @@
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package balancechecker
import (
"errors"
"math/big"
"strings"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
)
// Reference imports to suppress errors if they are not otherwise used.
var (
_ = errors.New
_ = big.NewInt
_ = strings.NewReader
_ = ethereum.NotFound
_ = bind.Bind
_ = common.Big1
_ = types.BloomLookup
_ = event.NewSubscription
_ = abi.ConvertType
)
// BalanceCheckerMetaData contains all meta data concerning the BalanceChecker contract.
var BalanceCheckerMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"users\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"balancesHash\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"balancesPerAddress\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"tokenBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
}
// BalanceCheckerABI is the input ABI used to generate the binding from.
// Deprecated: Use BalanceCheckerMetaData.ABI instead.
var BalanceCheckerABI = BalanceCheckerMetaData.ABI
// BalanceChecker is an auto generated Go binding around an Ethereum contract.
type BalanceChecker struct {
BalanceCheckerCaller // Read-only binding to the contract
BalanceCheckerTransactor // Write-only binding to the contract
BalanceCheckerFilterer // Log filterer for contract events
}
// BalanceCheckerCaller is an auto generated read-only Go binding around an Ethereum contract.
type BalanceCheckerCaller struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// BalanceCheckerTransactor is an auto generated write-only Go binding around an Ethereum contract.
type BalanceCheckerTransactor struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// BalanceCheckerFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
type BalanceCheckerFilterer struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// BalanceCheckerSession is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type BalanceCheckerSession struct {
Contract *BalanceChecker // Generic contract binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// BalanceCheckerCallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type BalanceCheckerCallerSession struct {
Contract *BalanceCheckerCaller // Generic contract caller binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
}
// BalanceCheckerTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type BalanceCheckerTransactorSession struct {
Contract *BalanceCheckerTransactor // Generic contract transactor binding to set the session for
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// BalanceCheckerRaw is an auto generated low-level Go binding around an Ethereum contract.
type BalanceCheckerRaw struct {
Contract *BalanceChecker // Generic contract binding to access the raw methods on
}
// BalanceCheckerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type BalanceCheckerCallerRaw struct {
Contract *BalanceCheckerCaller // Generic read-only contract binding to access the raw methods on
}
// BalanceCheckerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type BalanceCheckerTransactorRaw struct {
Contract *BalanceCheckerTransactor // Generic write-only contract binding to access the raw methods on
}
// NewBalanceChecker creates a new instance of BalanceChecker, bound to a specific deployed contract.
func NewBalanceChecker(address common.Address, backend bind.ContractBackend) (*BalanceChecker, error) {
contract, err := bindBalanceChecker(address, backend, backend, backend)
if err != nil {
return nil, err
}
return &BalanceChecker{BalanceCheckerCaller: BalanceCheckerCaller{contract: contract}, BalanceCheckerTransactor: BalanceCheckerTransactor{contract: contract}, BalanceCheckerFilterer: BalanceCheckerFilterer{contract: contract}}, nil
}
// NewBalanceCheckerCaller creates a new read-only instance of BalanceChecker, bound to a specific deployed contract.
func NewBalanceCheckerCaller(address common.Address, caller bind.ContractCaller) (*BalanceCheckerCaller, error) {
contract, err := bindBalanceChecker(address, caller, nil, nil)
if err != nil {
return nil, err
}
return &BalanceCheckerCaller{contract: contract}, nil
}
// NewBalanceCheckerTransactor creates a new write-only instance of BalanceChecker, bound to a specific deployed contract.
func NewBalanceCheckerTransactor(address common.Address, transactor bind.ContractTransactor) (*BalanceCheckerTransactor, error) {
contract, err := bindBalanceChecker(address, nil, transactor, nil)
if err != nil {
return nil, err
}
return &BalanceCheckerTransactor{contract: contract}, nil
}
// NewBalanceCheckerFilterer creates a new log filterer instance of BalanceChecker, bound to a specific deployed contract.
func NewBalanceCheckerFilterer(address common.Address, filterer bind.ContractFilterer) (*BalanceCheckerFilterer, error) {
contract, err := bindBalanceChecker(address, nil, nil, filterer)
if err != nil {
return nil, err
}
return &BalanceCheckerFilterer{contract: contract}, nil
}
// bindBalanceChecker binds a generic wrapper to an already deployed contract.
func bindBalanceChecker(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
parsed, err := BalanceCheckerMetaData.GetAbi()
if err != nil {
return nil, err
}
return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_BalanceChecker *BalanceCheckerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _BalanceChecker.Contract.BalanceCheckerCaller.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_BalanceChecker *BalanceCheckerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _BalanceChecker.Contract.BalanceCheckerTransactor.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_BalanceChecker *BalanceCheckerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _BalanceChecker.Contract.BalanceCheckerTransactor.contract.Transact(opts, method, params...)
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_BalanceChecker *BalanceCheckerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _BalanceChecker.Contract.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_BalanceChecker *BalanceCheckerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _BalanceChecker.Contract.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_BalanceChecker *BalanceCheckerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _BalanceChecker.Contract.contract.Transact(opts, method, params...)
}
// BalancesHash is a free data retrieval call binding the contract method 0x23c0503e.
//
// Solidity: function balancesHash(address[] users, address[] tokens) view returns(uint256, bytes32[])
func (_BalanceChecker *BalanceCheckerCaller) BalancesHash(opts *bind.CallOpts, users []common.Address, tokens []common.Address) (*big.Int, [][32]byte, error) {
var out []interface{}
err := _BalanceChecker.contract.Call(opts, &out, "balancesHash", users, tokens)
if err != nil {
return *new(*big.Int), *new([][32]byte), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
out1 := *abi.ConvertType(out[1], new([][32]byte)).(*[][32]byte)
return out0, out1, err
}
// BalancesHash is a free data retrieval call binding the contract method 0x23c0503e.
//
// Solidity: function balancesHash(address[] users, address[] tokens) view returns(uint256, bytes32[])
func (_BalanceChecker *BalanceCheckerSession) BalancesHash(users []common.Address, tokens []common.Address) (*big.Int, [][32]byte, error) {
return _BalanceChecker.Contract.BalancesHash(&_BalanceChecker.CallOpts, users, tokens)
}
// BalancesHash is a free data retrieval call binding the contract method 0x23c0503e.
//
// Solidity: function balancesHash(address[] users, address[] tokens) view returns(uint256, bytes32[])
func (_BalanceChecker *BalanceCheckerCallerSession) BalancesHash(users []common.Address, tokens []common.Address) (*big.Int, [][32]byte, error) {
return _BalanceChecker.Contract.BalancesHash(&_BalanceChecker.CallOpts, users, tokens)
}
// BalancesPerAddress is a free data retrieval call binding the contract method 0x1a55d770.
//
// Solidity: function balancesPerAddress(address user, address[] tokens) view returns(uint256[])
func (_BalanceChecker *BalanceCheckerCaller) BalancesPerAddress(opts *bind.CallOpts, user common.Address, tokens []common.Address) ([]*big.Int, error) {
var out []interface{}
err := _BalanceChecker.contract.Call(opts, &out, "balancesPerAddress", user, tokens)
if err != nil {
return *new([]*big.Int), err
}
out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int)
return out0, err
}
// BalancesPerAddress is a free data retrieval call binding the contract method 0x1a55d770.
//
// Solidity: function balancesPerAddress(address user, address[] tokens) view returns(uint256[])
func (_BalanceChecker *BalanceCheckerSession) BalancesPerAddress(user common.Address, tokens []common.Address) ([]*big.Int, error) {
return _BalanceChecker.Contract.BalancesPerAddress(&_BalanceChecker.CallOpts, user, tokens)
}
// BalancesPerAddress is a free data retrieval call binding the contract method 0x1a55d770.
//
// Solidity: function balancesPerAddress(address user, address[] tokens) view returns(uint256[])
func (_BalanceChecker *BalanceCheckerCallerSession) BalancesPerAddress(user common.Address, tokens []common.Address) ([]*big.Int, error) {
return _BalanceChecker.Contract.BalancesPerAddress(&_BalanceChecker.CallOpts, user, tokens)
}
// TokenBalance is a free data retrieval call binding the contract method 0x1049334f.
//
// Solidity: function tokenBalance(address user, address token) view returns(uint256)
func (_BalanceChecker *BalanceCheckerCaller) TokenBalance(opts *bind.CallOpts, user common.Address, token common.Address) (*big.Int, error) {
var out []interface{}
err := _BalanceChecker.contract.Call(opts, &out, "tokenBalance", user, token)
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// TokenBalance is a free data retrieval call binding the contract method 0x1049334f.
//
// Solidity: function tokenBalance(address user, address token) view returns(uint256)
func (_BalanceChecker *BalanceCheckerSession) TokenBalance(user common.Address, token common.Address) (*big.Int, error) {
return _BalanceChecker.Contract.TokenBalance(&_BalanceChecker.CallOpts, user, token)
}
// TokenBalance is a free data retrieval call binding the contract method 0x1049334f.
//
// Solidity: function tokenBalance(address user, address token) view returns(uint256)
func (_BalanceChecker *BalanceCheckerCallerSession) TokenBalance(user common.Address, token common.Address) (*big.Int, error) {
return _BalanceChecker.Contract.TokenBalance(&_BalanceChecker.CallOpts, user, token)
}

View File

@@ -0,0 +1,46 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
// ERC20 contract interface
abstract contract Token {
function balanceOf(address) public view virtual returns (uint);
}
contract BalanceChecker {
function tokenBalance(
address user,
address token
) public view returns (uint) {
return Token(token).balanceOf(user);
}
function balancesPerAddress(
address user,
address[] memory tokens
) public view returns (uint[] memory) {
uint[] memory addrBalances = new uint[](
tokens.length + 1
);
for (uint i = 0; i < tokens.length; i++) {
addrBalances[i] = tokenBalance(user, tokens[i]);
}
addrBalances[tokens.length] = user.balance;
return addrBalances;
}
function balancesHash(
address[] calldata users,
address[] calldata tokens
) external view returns (uint256, bytes32[] memory) {
bytes32[] memory addrBalances = new bytes32[](users.length);
for (uint i = 0; i < users.length; i++) {
addrBalances[i] = keccak256(
abi.encodePacked(balancesPerAddress(users[i], tokens))
);
}
return (block.number, addrBalances);
}
}

View File

@@ -0,0 +1,30 @@
package balancechecker
import (
"errors"
"github.com/ethereum/go-ethereum/common"
)
var errorNotAvailableOnChainID = errors.New("BalanceChecker not available for chainID")
var contractDataByChainID = map[uint64]common.Address{
1: common.HexToAddress("0x040EA8bFE441597849A9456182fa46D38B75BC05"), // mainnet
10: common.HexToAddress("0x55bD303eA3D50FC982A8a5b43972d7f38D129bbF"), // optimism
42161: common.HexToAddress("0x54764eF12d29b249fDC7FC3caDc039955A396A8e"), // arbitrum
5: common.HexToAddress("0xA5522A3194B78Dd231b64d0ccd6deA6156DCa7C8"), // goerli
421613: common.HexToAddress("0x54764eF12d29b249fDC7FC3caDc039955A396A8e"), // goerli arbitrum
420: common.HexToAddress("0x55bD303eA3D50FC982A8a5b43972d7f38D129bbF"), // goerli optimism
11155111: common.HexToAddress("0x55bD303eA3D50FC982A8a5b43972d7f38D129bbF"), // sepolia
421614: common.HexToAddress("0x54764eF12d29b249fDC7FC3caDc039955A396A8e"), // sepolia arbitrum
11155420: common.HexToAddress("0x55bD303eA3D50FC982A8a5b43972d7f38D129bbF"), // sepolia optimism
777333: common.HexToAddress("0x0000000000000000000000000000000010777333"), // unit tests
}
func ContractAddress(chainID uint64) (common.Address, error) {
contract, exists := contractDataByChainID[chainID]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
return contract, nil
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
package celer
//go:generate abigen --abi bridge.abi --pkg celer --out bridge.go

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,29 @@
package communitytokendeployer
import (
"errors"
"github.com/ethereum/go-ethereum/common"
)
var errorNotAvailableOnChainID = errors.New("deployer contract not available for chainID")
// addresses can be found on https://github.com/status-im/communities-contracts#deployments
var contractAddressByChainID = map[uint64]common.Address{
1: common.HexToAddress("0xB3Ef5B0825D5f665bE14394eea41E684CE96A4c5"), // Mainnet
5: common.HexToAddress("0x81f4951ff8859d305F47A4574B206cF64C0d2645"), // Goerli
10: common.HexToAddress("0x31463D22750324C8721FF7751584EF62F2ff93b3"), // Optimism
420: common.HexToAddress("0xfFa8A255D905c909379859eA45B959D090DDC2d4"), // Optimism Goerli
42161: common.HexToAddress("0x744Fd6e98dad09Fb8CCF530B5aBd32B56D64943b"), // Arbitrum
421613: common.HexToAddress("0x7Ff554af5b6624db2135E4364F416d1D397f43e6"), // Arbitrum Goerli
11155111: common.HexToAddress("0xCDE984e57cdb88c70b53437cc694345B646371f9"), // Sepolia
421614: common.HexToAddress("0x7Ff554af5b6624db2135E4364F416d1D397f43e6"), // Arbitrum Sepolia
}
func ContractAddress(chainID uint64) (common.Address, error) {
addr, exists := contractAddressByChainID[chainID]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
return addr, nil
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,254 @@
package contracts
import (
"errors"
"github.com/ethereum/go-ethereum/common"
"github.com/status-im/status-go/contracts/balancechecker"
"github.com/status-im/status-go/contracts/directory"
"github.com/status-im/status-go/contracts/ethscan"
"github.com/status-im/status-go/contracts/hop"
hopBridge "github.com/status-im/status-go/contracts/hop/bridge"
hopSwap "github.com/status-im/status-go/contracts/hop/swap"
hopWrapper "github.com/status-im/status-go/contracts/hop/wrapper"
"github.com/status-im/status-go/contracts/ierc20"
"github.com/status-im/status-go/contracts/registrar"
"github.com/status-im/status-go/contracts/resolver"
"github.com/status-im/status-go/contracts/snt"
"github.com/status-im/status-go/contracts/stickers"
"github.com/status-im/status-go/rpc"
)
type ContractMaker struct {
RPCClient *rpc.Client
}
func NewContractMaker(client *rpc.Client) (*ContractMaker, error) {
if client == nil {
return nil, errors.New("could not initialize ContractMaker with an rpc client")
}
return &ContractMaker{RPCClient: client}, nil
}
func (c *ContractMaker) NewRegistryWithAddress(chainID uint64, address common.Address) (*resolver.ENSRegistryWithFallback, error) {
backend, err := c.RPCClient.EthClient(chainID)
if err != nil {
return nil, err
}
return resolver.NewENSRegistryWithFallback(
address,
backend,
)
}
func (c *ContractMaker) NewRegistry(chainID uint64) (*resolver.ENSRegistryWithFallback, error) {
contractAddr, err := resolver.ContractAddress(chainID)
if err != nil {
return nil, err
}
return c.NewRegistryWithAddress(chainID, contractAddr)
}
func (c *ContractMaker) NewPublicResolver(chainID uint64, resolverAddress *common.Address) (*resolver.PublicResolver, error) {
backend, err := c.RPCClient.EthClient(chainID)
if err != nil {
return nil, err
}
return resolver.NewPublicResolver(*resolverAddress, backend)
}
func (c *ContractMaker) NewUsernameRegistrar(chainID uint64, contractAddr common.Address) (*registrar.UsernameRegistrar, error) {
backend, err := c.RPCClient.EthClient(chainID)
if err != nil {
return nil, err
}
return registrar.NewUsernameRegistrar(
contractAddr,
backend,
)
}
func (c *ContractMaker) NewERC20(chainID uint64, contractAddr common.Address) (*ierc20.IERC20, error) {
backend, err := c.RPCClient.EthClient(chainID)
if err != nil {
return nil, err
}
return ierc20.NewIERC20(
contractAddr,
backend,
)
}
func (c *ContractMaker) NewSNT(chainID uint64) (*snt.SNT, error) {
contractAddr, err := snt.ContractAddress(chainID)
if err != nil {
return nil, err
}
backend, err := c.RPCClient.EthClient(chainID)
if err != nil {
return nil, err
}
return snt.NewSNT(contractAddr, backend)
}
func (c *ContractMaker) NewStickerType(chainID uint64) (*stickers.StickerType, error) {
contractAddr, err := stickers.StickerTypeContractAddress(chainID)
if err != nil {
return nil, err
}
backend, err := c.RPCClient.EthClient(chainID)
if err != nil {
return nil, err
}
return stickers.NewStickerType(
contractAddr,
backend,
)
}
func (c *ContractMaker) NewStickerMarket(chainID uint64) (*stickers.StickerMarket, error) {
contractAddr, err := stickers.StickerMarketContractAddress(chainID)
if err != nil {
return nil, err
}
backend, err := c.RPCClient.EthClient(chainID)
if err != nil {
return nil, err
}
return stickers.NewStickerMarket(
contractAddr,
backend,
)
}
func (c *ContractMaker) NewStickerPack(chainID uint64) (*stickers.StickerPack, error) {
contractAddr, err := stickers.StickerPackContractAddress(chainID)
if err != nil {
return nil, err
}
backend, err := c.RPCClient.EthClient(chainID)
if err != nil {
return nil, err
}
return stickers.NewStickerPack(
contractAddr,
backend,
)
}
func (c *ContractMaker) NewDirectory(chainID uint64) (*directory.Directory, error) {
contractAddr, err := directory.ContractAddress(chainID)
if err != nil {
return nil, err
}
backend, err := c.RPCClient.EthClient(chainID)
if err != nil {
return nil, err
}
return directory.NewDirectory(
contractAddr,
backend,
)
}
func (c *ContractMaker) NewEthScan(chainID uint64) (*ethscan.BalanceScanner, uint, error) {
contractAddr, err := ethscan.ContractAddress(chainID)
if err != nil {
return nil, 0, err
}
contractCreatedAt, err := ethscan.ContractCreatedAt(chainID)
if err != nil {
return nil, 0, err
}
backend, err := c.RPCClient.EthClient(chainID)
if err != nil {
return nil, 0, err
}
scanner, err := ethscan.NewBalanceScanner(
contractAddr,
backend,
)
return scanner, contractCreatedAt, err
}
func (c *ContractMaker) NewBalanceChecker(chainID uint64) (*balancechecker.BalanceChecker, error) {
contractAddr, err := balancechecker.ContractAddress(chainID)
if err != nil {
return nil, err
}
backend, err := c.RPCClient.EthClient(chainID)
if err != nil {
return nil, err
}
return balancechecker.NewBalanceChecker(
contractAddr,
backend,
)
}
func (c *ContractMaker) NewHopL2SaddlSwap(chainID uint64, symbol string) (*hopSwap.HopSwap, error) {
contractAddr, err := hop.L2SaddleSwapContractAddress(chainID, symbol)
if err != nil {
return nil, err
}
backend, err := c.RPCClient.EthClient(chainID)
if err != nil {
return nil, err
}
return hopSwap.NewHopSwap(
contractAddr,
backend,
)
}
func (c *ContractMaker) NewHopL1Bridge(chainID uint64, symbol string) (*hopBridge.HopBridge, error) {
contractAddr, err := hop.L1BridgeContractAddress(chainID, symbol)
if err != nil {
return nil, err
}
backend, err := c.RPCClient.EthClient(chainID)
if err != nil {
return nil, err
}
return hopBridge.NewHopBridge(
contractAddr,
backend,
)
}
func (c *ContractMaker) NewHopL2AmmWrapper(chainID uint64, symbol string) (*hopWrapper.HopWrapper, error) {
contractAddr, err := hop.L2AmmWrapperContractAddress(chainID, symbol)
if err != nil {
return nil, err
}
backend, err := c.RPCClient.EthClient(chainID)
if err != nil {
return nil, err
}
return hopWrapper.NewHopWrapper(
contractAddr,
backend,
)
}

View File

@@ -0,0 +1,22 @@
package directory
import (
"errors"
"github.com/ethereum/go-ethereum/common"
)
var errorNotAvailableOnChainID = errors.New("not available for chainID")
var contractAddressByChainID = map[uint64]common.Address{
10: common.HexToAddress("0xA8d270048a086F5807A8dc0a9ae0e96280C41e3A"), // optimism mainnet
420: common.HexToAddress("0xB3Ef5B0825D5f665bE14394eea41E684CE96A4c5"), // optimism goerli testnet
}
func ContractAddress(chainID uint64) (common.Address, error) {
addr, exists := contractAddressByChainID[chainID]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
return addr, nil
}

View File

@@ -0,0 +1,147 @@
[
{
"inputs": [
{
"internalType": "address",
"name": "_votingContract",
"type": "address"
},
{
"internalType": "address",
"name": "_featuredVotingContract",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "community",
"type": "bytes"
}
],
"name": "addCommunity",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "featuredVotingContract",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getCommunities",
"outputs": [
{
"internalType": "bytes[]",
"name": "",
"type": "bytes[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getFeaturedCommunities",
"outputs": [
{
"internalType": "bytes[]",
"name": "",
"type": "bytes[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "community",
"type": "bytes"
}
],
"name": "isCommunityFeatured",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "community",
"type": "bytes"
}
],
"name": "isCommunityInDirectory",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "community",
"type": "bytes"
}
],
"name": "removeCommunity",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes[]",
"name": "_featuredCommunities",
"type": "bytes[]"
}
],
"name": "setFeaturedCommunities",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "votingContract",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
]

View File

@@ -0,0 +1,430 @@
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package directory
import (
"errors"
"math/big"
"strings"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
)
// Reference imports to suppress errors if they are not otherwise used.
var (
_ = errors.New
_ = big.NewInt
_ = strings.NewReader
_ = ethereum.NotFound
_ = bind.Bind
_ = common.Big1
_ = types.BloomLookup
_ = event.NewSubscription
_ = abi.ConvertType
)
// DirectoryMetaData contains all meta data concerning the Directory contract.
var DirectoryMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_votingContract\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_featuredVotingContract\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"community\",\"type\":\"bytes\"}],\"name\":\"addCommunity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"featuredVotingContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCommunities\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeaturedCommunities\",\"outputs\":[{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"community\",\"type\":\"bytes\"}],\"name\":\"isCommunityFeatured\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"community\",\"type\":\"bytes\"}],\"name\":\"isCommunityInDirectory\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"community\",\"type\":\"bytes\"}],\"name\":\"removeCommunity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes[]\",\"name\":\"_featuredCommunities\",\"type\":\"bytes[]\"}],\"name\":\"setFeaturedCommunities\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"votingContract\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
}
// DirectoryABI is the input ABI used to generate the binding from.
// Deprecated: Use DirectoryMetaData.ABI instead.
var DirectoryABI = DirectoryMetaData.ABI
// Directory is an auto generated Go binding around an Ethereum contract.
type Directory struct {
DirectoryCaller // Read-only binding to the contract
DirectoryTransactor // Write-only binding to the contract
DirectoryFilterer // Log filterer for contract events
}
// DirectoryCaller is an auto generated read-only Go binding around an Ethereum contract.
type DirectoryCaller struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// DirectoryTransactor is an auto generated write-only Go binding around an Ethereum contract.
type DirectoryTransactor struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// DirectoryFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
type DirectoryFilterer struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// DirectorySession is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type DirectorySession struct {
Contract *Directory // Generic contract binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// DirectoryCallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type DirectoryCallerSession struct {
Contract *DirectoryCaller // Generic contract caller binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
}
// DirectoryTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type DirectoryTransactorSession struct {
Contract *DirectoryTransactor // Generic contract transactor binding to set the session for
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// DirectoryRaw is an auto generated low-level Go binding around an Ethereum contract.
type DirectoryRaw struct {
Contract *Directory // Generic contract binding to access the raw methods on
}
// DirectoryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type DirectoryCallerRaw struct {
Contract *DirectoryCaller // Generic read-only contract binding to access the raw methods on
}
// DirectoryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type DirectoryTransactorRaw struct {
Contract *DirectoryTransactor // Generic write-only contract binding to access the raw methods on
}
// NewDirectory creates a new instance of Directory, bound to a specific deployed contract.
func NewDirectory(address common.Address, backend bind.ContractBackend) (*Directory, error) {
contract, err := bindDirectory(address, backend, backend, backend)
if err != nil {
return nil, err
}
return &Directory{DirectoryCaller: DirectoryCaller{contract: contract}, DirectoryTransactor: DirectoryTransactor{contract: contract}, DirectoryFilterer: DirectoryFilterer{contract: contract}}, nil
}
// NewDirectoryCaller creates a new read-only instance of Directory, bound to a specific deployed contract.
func NewDirectoryCaller(address common.Address, caller bind.ContractCaller) (*DirectoryCaller, error) {
contract, err := bindDirectory(address, caller, nil, nil)
if err != nil {
return nil, err
}
return &DirectoryCaller{contract: contract}, nil
}
// NewDirectoryTransactor creates a new write-only instance of Directory, bound to a specific deployed contract.
func NewDirectoryTransactor(address common.Address, transactor bind.ContractTransactor) (*DirectoryTransactor, error) {
contract, err := bindDirectory(address, nil, transactor, nil)
if err != nil {
return nil, err
}
return &DirectoryTransactor{contract: contract}, nil
}
// NewDirectoryFilterer creates a new log filterer instance of Directory, bound to a specific deployed contract.
func NewDirectoryFilterer(address common.Address, filterer bind.ContractFilterer) (*DirectoryFilterer, error) {
contract, err := bindDirectory(address, nil, nil, filterer)
if err != nil {
return nil, err
}
return &DirectoryFilterer{contract: contract}, nil
}
// bindDirectory binds a generic wrapper to an already deployed contract.
func bindDirectory(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
parsed, err := DirectoryMetaData.GetAbi()
if err != nil {
return nil, err
}
return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_Directory *DirectoryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _Directory.Contract.DirectoryCaller.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_Directory *DirectoryRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _Directory.Contract.DirectoryTransactor.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_Directory *DirectoryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _Directory.Contract.DirectoryTransactor.contract.Transact(opts, method, params...)
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_Directory *DirectoryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _Directory.Contract.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_Directory *DirectoryTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _Directory.Contract.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_Directory *DirectoryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _Directory.Contract.contract.Transact(opts, method, params...)
}
// FeaturedVotingContract is a free data retrieval call binding the contract method 0x7475fe93.
//
// Solidity: function featuredVotingContract() view returns(address)
func (_Directory *DirectoryCaller) FeaturedVotingContract(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _Directory.contract.Call(opts, &out, "featuredVotingContract")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// FeaturedVotingContract is a free data retrieval call binding the contract method 0x7475fe93.
//
// Solidity: function featuredVotingContract() view returns(address)
func (_Directory *DirectorySession) FeaturedVotingContract() (common.Address, error) {
return _Directory.Contract.FeaturedVotingContract(&_Directory.CallOpts)
}
// FeaturedVotingContract is a free data retrieval call binding the contract method 0x7475fe93.
//
// Solidity: function featuredVotingContract() view returns(address)
func (_Directory *DirectoryCallerSession) FeaturedVotingContract() (common.Address, error) {
return _Directory.Contract.FeaturedVotingContract(&_Directory.CallOpts)
}
// GetCommunities is a free data retrieval call binding the contract method 0xc251b565.
//
// Solidity: function getCommunities() view returns(bytes[])
func (_Directory *DirectoryCaller) GetCommunities(opts *bind.CallOpts) ([][]byte, error) {
var out []interface{}
err := _Directory.contract.Call(opts, &out, "getCommunities")
if err != nil {
return *new([][]byte), err
}
out0 := *abi.ConvertType(out[0], new([][]byte)).(*[][]byte)
return out0, err
}
// GetCommunities is a free data retrieval call binding the contract method 0xc251b565.
//
// Solidity: function getCommunities() view returns(bytes[])
func (_Directory *DirectorySession) GetCommunities() ([][]byte, error) {
return _Directory.Contract.GetCommunities(&_Directory.CallOpts)
}
// GetCommunities is a free data retrieval call binding the contract method 0xc251b565.
//
// Solidity: function getCommunities() view returns(bytes[])
func (_Directory *DirectoryCallerSession) GetCommunities() ([][]byte, error) {
return _Directory.Contract.GetCommunities(&_Directory.CallOpts)
}
// GetFeaturedCommunities is a free data retrieval call binding the contract method 0x967961c6.
//
// Solidity: function getFeaturedCommunities() view returns(bytes[])
func (_Directory *DirectoryCaller) GetFeaturedCommunities(opts *bind.CallOpts) ([][]byte, error) {
var out []interface{}
err := _Directory.contract.Call(opts, &out, "getFeaturedCommunities")
if err != nil {
return *new([][]byte), err
}
out0 := *abi.ConvertType(out[0], new([][]byte)).(*[][]byte)
return out0, err
}
// GetFeaturedCommunities is a free data retrieval call binding the contract method 0x967961c6.
//
// Solidity: function getFeaturedCommunities() view returns(bytes[])
func (_Directory *DirectorySession) GetFeaturedCommunities() ([][]byte, error) {
return _Directory.Contract.GetFeaturedCommunities(&_Directory.CallOpts)
}
// GetFeaturedCommunities is a free data retrieval call binding the contract method 0x967961c6.
//
// Solidity: function getFeaturedCommunities() view returns(bytes[])
func (_Directory *DirectoryCallerSession) GetFeaturedCommunities() ([][]byte, error) {
return _Directory.Contract.GetFeaturedCommunities(&_Directory.CallOpts)
}
// IsCommunityFeatured is a free data retrieval call binding the contract method 0xf6a18e62.
//
// Solidity: function isCommunityFeatured(bytes community) view returns(bool)
func (_Directory *DirectoryCaller) IsCommunityFeatured(opts *bind.CallOpts, community []byte) (bool, error) {
var out []interface{}
err := _Directory.contract.Call(opts, &out, "isCommunityFeatured", community)
if err != nil {
return *new(bool), err
}
out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
return out0, err
}
// IsCommunityFeatured is a free data retrieval call binding the contract method 0xf6a18e62.
//
// Solidity: function isCommunityFeatured(bytes community) view returns(bool)
func (_Directory *DirectorySession) IsCommunityFeatured(community []byte) (bool, error) {
return _Directory.Contract.IsCommunityFeatured(&_Directory.CallOpts, community)
}
// IsCommunityFeatured is a free data retrieval call binding the contract method 0xf6a18e62.
//
// Solidity: function isCommunityFeatured(bytes community) view returns(bool)
func (_Directory *DirectoryCallerSession) IsCommunityFeatured(community []byte) (bool, error) {
return _Directory.Contract.IsCommunityFeatured(&_Directory.CallOpts, community)
}
// IsCommunityInDirectory is a free data retrieval call binding the contract method 0xb3dbb52a.
//
// Solidity: function isCommunityInDirectory(bytes community) view returns(bool)
func (_Directory *DirectoryCaller) IsCommunityInDirectory(opts *bind.CallOpts, community []byte) (bool, error) {
var out []interface{}
err := _Directory.contract.Call(opts, &out, "isCommunityInDirectory", community)
if err != nil {
return *new(bool), err
}
out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
return out0, err
}
// IsCommunityInDirectory is a free data retrieval call binding the contract method 0xb3dbb52a.
//
// Solidity: function isCommunityInDirectory(bytes community) view returns(bool)
func (_Directory *DirectorySession) IsCommunityInDirectory(community []byte) (bool, error) {
return _Directory.Contract.IsCommunityInDirectory(&_Directory.CallOpts, community)
}
// IsCommunityInDirectory is a free data retrieval call binding the contract method 0xb3dbb52a.
//
// Solidity: function isCommunityInDirectory(bytes community) view returns(bool)
func (_Directory *DirectoryCallerSession) IsCommunityInDirectory(community []byte) (bool, error) {
return _Directory.Contract.IsCommunityInDirectory(&_Directory.CallOpts, community)
}
// VotingContract is a free data retrieval call binding the contract method 0xc1fc006a.
//
// Solidity: function votingContract() view returns(address)
func (_Directory *DirectoryCaller) VotingContract(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _Directory.contract.Call(opts, &out, "votingContract")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// VotingContract is a free data retrieval call binding the contract method 0xc1fc006a.
//
// Solidity: function votingContract() view returns(address)
func (_Directory *DirectorySession) VotingContract() (common.Address, error) {
return _Directory.Contract.VotingContract(&_Directory.CallOpts)
}
// VotingContract is a free data retrieval call binding the contract method 0xc1fc006a.
//
// Solidity: function votingContract() view returns(address)
func (_Directory *DirectoryCallerSession) VotingContract() (common.Address, error) {
return _Directory.Contract.VotingContract(&_Directory.CallOpts)
}
// AddCommunity is a paid mutator transaction binding the contract method 0x74837935.
//
// Solidity: function addCommunity(bytes community) returns()
func (_Directory *DirectoryTransactor) AddCommunity(opts *bind.TransactOpts, community []byte) (*types.Transaction, error) {
return _Directory.contract.Transact(opts, "addCommunity", community)
}
// AddCommunity is a paid mutator transaction binding the contract method 0x74837935.
//
// Solidity: function addCommunity(bytes community) returns()
func (_Directory *DirectorySession) AddCommunity(community []byte) (*types.Transaction, error) {
return _Directory.Contract.AddCommunity(&_Directory.TransactOpts, community)
}
// AddCommunity is a paid mutator transaction binding the contract method 0x74837935.
//
// Solidity: function addCommunity(bytes community) returns()
func (_Directory *DirectoryTransactorSession) AddCommunity(community []byte) (*types.Transaction, error) {
return _Directory.Contract.AddCommunity(&_Directory.TransactOpts, community)
}
// RemoveCommunity is a paid mutator transaction binding the contract method 0x3c01b93c.
//
// Solidity: function removeCommunity(bytes community) returns()
func (_Directory *DirectoryTransactor) RemoveCommunity(opts *bind.TransactOpts, community []byte) (*types.Transaction, error) {
return _Directory.contract.Transact(opts, "removeCommunity", community)
}
// RemoveCommunity is a paid mutator transaction binding the contract method 0x3c01b93c.
//
// Solidity: function removeCommunity(bytes community) returns()
func (_Directory *DirectorySession) RemoveCommunity(community []byte) (*types.Transaction, error) {
return _Directory.Contract.RemoveCommunity(&_Directory.TransactOpts, community)
}
// RemoveCommunity is a paid mutator transaction binding the contract method 0x3c01b93c.
//
// Solidity: function removeCommunity(bytes community) returns()
func (_Directory *DirectoryTransactorSession) RemoveCommunity(community []byte) (*types.Transaction, error) {
return _Directory.Contract.RemoveCommunity(&_Directory.TransactOpts, community)
}
// SetFeaturedCommunities is a paid mutator transaction binding the contract method 0xd62879f1.
//
// Solidity: function setFeaturedCommunities(bytes[] _featuredCommunities) returns()
func (_Directory *DirectoryTransactor) SetFeaturedCommunities(opts *bind.TransactOpts, _featuredCommunities [][]byte) (*types.Transaction, error) {
return _Directory.contract.Transact(opts, "setFeaturedCommunities", _featuredCommunities)
}
// SetFeaturedCommunities is a paid mutator transaction binding the contract method 0xd62879f1.
//
// Solidity: function setFeaturedCommunities(bytes[] _featuredCommunities) returns()
func (_Directory *DirectorySession) SetFeaturedCommunities(_featuredCommunities [][]byte) (*types.Transaction, error) {
return _Directory.Contract.SetFeaturedCommunities(&_Directory.TransactOpts, _featuredCommunities)
}
// SetFeaturedCommunities is a paid mutator transaction binding the contract method 0xd62879f1.
//
// Solidity: function setFeaturedCommunities(bytes[] _featuredCommunities) returns()
func (_Directory *DirectoryTransactorSession) SetFeaturedCommunities(_featuredCommunities [][]byte) (*types.Transaction, error) {
return _Directory.Contract.SetFeaturedCommunities(&_Directory.TransactOpts, _featuredCommunities)
}

View File

@@ -0,0 +1,3 @@
package directory
//go:generate abigen -abi directory.abi -pkg directory -out directory.go

View File

@@ -0,0 +1,43 @@
package ethscan
import (
"errors"
"github.com/ethereum/go-ethereum/common"
)
var errorNotAvailableOnChainID = errors.New("not available for chainID")
type ContractData struct {
Address common.Address
CreatedAtBlock uint
}
var contractDataByChainID = map[uint64]ContractData{
1: {common.HexToAddress("0x08A8fDBddc160A7d5b957256b903dCAb1aE512C5"), 12_194_222}, // mainnet
5: {common.HexToAddress("0x08A8fDBddc160A7d5b957256b903dCAb1aE512C5"), 4_578_854}, // goerli
10: {common.HexToAddress("0x9e5076df494fc949abc4461f4e57592b81517d81"), 34_421_097}, // optimism
420: {common.HexToAddress("0xf532c75239fa61b66d31e73f44300c46da41aadd"), 2_236_534}, // goerli optimism
42161: {common.HexToAddress("0xbb85398092b83a016935a17fc857507b7851a071"), 70_031_945}, // arbitrum
421613: {common.HexToAddress("0xec21ebe1918e8975fc0cd0c7747d318c00c0acd5"), 818_155}, // goerli arbitrum
777333: {common.HexToAddress("0x0000000000000000000000000000000000777333"), 50}, // unit tests
11155111: {common.HexToAddress("0xec21ebe1918e8975fc0cd0c7747d318c00c0acd5"), 4_366_506}, // sepolia
421614: {common.HexToAddress("0xec21Ebe1918E8975FC0CD0c7747D318C00C0aCd5"), 553_947}, // sepolia arbitrum
11155420: {common.HexToAddress("0xec21ebe1918e8975fc0cd0c7747d318c00c0acd5"), 7_362_011}, // sepolia optimism
}
func ContractAddress(chainID uint64) (common.Address, error) {
contract, exists := contractDataByChainID[chainID]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
return contract.Address, nil
}
func ContractCreatedAt(chainID uint64) (uint, error) {
contract, exists := contractDataByChainID[chainID]
if !exists {
return 0, errorNotAvailableOnChainID
}
return contract.CreatedAtBlock, nil
}

View File

@@ -0,0 +1,3 @@
package ethscan
//go:generate abigen -sol ethscan.sol -pkg ethscan -out ethscan.go

View File

@@ -0,0 +1,342 @@
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package ethscan
import (
"math/big"
"strings"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
)
// Reference imports to suppress errors if they are not otherwise used.
var (
_ = big.NewInt
_ = strings.NewReader
_ = ethereum.NotFound
_ = bind.Bind
_ = common.Big1
_ = types.BloomLookup
_ = event.NewSubscription
)
// BalanceScannerResult is an auto generated low-level Go binding around an user-defined struct.
type BalanceScannerResult struct {
Success bool
Data []byte
}
// BalanceScannerABI is the input ABI used to generate the binding from.
const BalanceScannerABI = "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"contracts\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"},{\"internalType\":\"uint256\",\"name\":\"gas\",\"type\":\"uint256\"}],\"name\":\"call\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structBalanceScanner.Result[]\",\"name\":\"results\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"contracts\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"data\",\"type\":\"bytes[]\"}],\"name\":\"call\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structBalanceScanner.Result[]\",\"name\":\"results\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"}],\"name\":\"etherBalances\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structBalanceScanner.Result[]\",\"name\":\"results\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"addresses\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"tokenBalances\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structBalanceScanner.Result[]\",\"name\":\"results\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"contracts\",\"type\":\"address[]\"}],\"name\":\"tokensBalance\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structBalanceScanner.Result[]\",\"name\":\"results\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]"
// BalanceScannerFuncSigs maps the 4-byte function signature to its string representation.
var BalanceScannerFuncSigs = map[string]string{
"458b3a7c": "call(address[],bytes[])",
"36738374": "call(address[],bytes[],uint256)",
"dbdbb51b": "etherBalances(address[])",
"aad33091": "tokenBalances(address[],address)",
"e5da1b68": "tokensBalance(address,address[])",
}
// BalanceScanner is an auto generated Go binding around an Ethereum contract.
type BalanceScanner struct {
BalanceScannerCaller // Read-only binding to the contract
BalanceScannerTransactor // Write-only binding to the contract
BalanceScannerFilterer // Log filterer for contract events
}
// BalanceScannerCaller is an auto generated read-only Go binding around an Ethereum contract.
type BalanceScannerCaller struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// BalanceScannerTransactor is an auto generated write-only Go binding around an Ethereum contract.
type BalanceScannerTransactor struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// BalanceScannerFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
type BalanceScannerFilterer struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// BalanceScannerSession is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type BalanceScannerSession struct {
Contract *BalanceScanner // Generic contract binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// BalanceScannerCallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type BalanceScannerCallerSession struct {
Contract *BalanceScannerCaller // Generic contract caller binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
}
// BalanceScannerTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type BalanceScannerTransactorSession struct {
Contract *BalanceScannerTransactor // Generic contract transactor binding to set the session for
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// BalanceScannerRaw is an auto generated low-level Go binding around an Ethereum contract.
type BalanceScannerRaw struct {
Contract *BalanceScanner // Generic contract binding to access the raw methods on
}
// BalanceScannerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type BalanceScannerCallerRaw struct {
Contract *BalanceScannerCaller // Generic read-only contract binding to access the raw methods on
}
// BalanceScannerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type BalanceScannerTransactorRaw struct {
Contract *BalanceScannerTransactor // Generic write-only contract binding to access the raw methods on
}
// NewBalanceScanner creates a new instance of BalanceScanner, bound to a specific deployed contract.
func NewBalanceScanner(address common.Address, backend bind.ContractBackend) (*BalanceScanner, error) {
contract, err := bindBalanceScanner(address, backend, backend, backend)
if err != nil {
return nil, err
}
return &BalanceScanner{BalanceScannerCaller: BalanceScannerCaller{contract: contract}, BalanceScannerTransactor: BalanceScannerTransactor{contract: contract}, BalanceScannerFilterer: BalanceScannerFilterer{contract: contract}}, nil
}
// NewBalanceScannerCaller creates a new read-only instance of BalanceScanner, bound to a specific deployed contract.
func NewBalanceScannerCaller(address common.Address, caller bind.ContractCaller) (*BalanceScannerCaller, error) {
contract, err := bindBalanceScanner(address, caller, nil, nil)
if err != nil {
return nil, err
}
return &BalanceScannerCaller{contract: contract}, nil
}
// NewBalanceScannerTransactor creates a new write-only instance of BalanceScanner, bound to a specific deployed contract.
func NewBalanceScannerTransactor(address common.Address, transactor bind.ContractTransactor) (*BalanceScannerTransactor, error) {
contract, err := bindBalanceScanner(address, nil, transactor, nil)
if err != nil {
return nil, err
}
return &BalanceScannerTransactor{contract: contract}, nil
}
// NewBalanceScannerFilterer creates a new log filterer instance of BalanceScanner, bound to a specific deployed contract.
func NewBalanceScannerFilterer(address common.Address, filterer bind.ContractFilterer) (*BalanceScannerFilterer, error) {
contract, err := bindBalanceScanner(address, nil, nil, filterer)
if err != nil {
return nil, err
}
return &BalanceScannerFilterer{contract: contract}, nil
}
// bindBalanceScanner binds a generic wrapper to an already deployed contract.
func bindBalanceScanner(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
parsed, err := abi.JSON(strings.NewReader(BalanceScannerABI))
if err != nil {
return nil, err
}
return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_BalanceScanner *BalanceScannerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _BalanceScanner.Contract.BalanceScannerCaller.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_BalanceScanner *BalanceScannerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _BalanceScanner.Contract.BalanceScannerTransactor.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_BalanceScanner *BalanceScannerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _BalanceScanner.Contract.BalanceScannerTransactor.contract.Transact(opts, method, params...)
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_BalanceScanner *BalanceScannerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _BalanceScanner.Contract.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_BalanceScanner *BalanceScannerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _BalanceScanner.Contract.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_BalanceScanner *BalanceScannerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _BalanceScanner.Contract.contract.Transact(opts, method, params...)
}
// Call is a free data retrieval call binding the contract method 0x36738374.
//
// Solidity: function call(address[] contracts, bytes[] data, uint256 gas) view returns((bool,bytes)[] results)
func (_BalanceScanner *BalanceScannerCaller) Call(opts *bind.CallOpts, contracts []common.Address, data [][]byte, gas *big.Int) ([]BalanceScannerResult, error) {
var out []interface{}
err := _BalanceScanner.contract.Call(opts, &out, "call", contracts, data, gas)
if err != nil {
return *new([]BalanceScannerResult), err
}
out0 := *abi.ConvertType(out[0], new([]BalanceScannerResult)).(*[]BalanceScannerResult)
return out0, err
}
// Call is a free data retrieval call binding the contract method 0x36738374.
//
// Solidity: function call(address[] contracts, bytes[] data, uint256 gas) view returns((bool,bytes)[] results)
func (_BalanceScanner *BalanceScannerSession) Call(contracts []common.Address, data [][]byte, gas *big.Int) ([]BalanceScannerResult, error) {
return _BalanceScanner.Contract.Call(&_BalanceScanner.CallOpts, contracts, data, gas)
}
// Call is a free data retrieval call binding the contract method 0x36738374.
//
// Solidity: function call(address[] contracts, bytes[] data, uint256 gas) view returns((bool,bytes)[] results)
func (_BalanceScanner *BalanceScannerCallerSession) Call(contracts []common.Address, data [][]byte, gas *big.Int) ([]BalanceScannerResult, error) {
return _BalanceScanner.Contract.Call(&_BalanceScanner.CallOpts, contracts, data, gas)
}
// Call0 is a free data retrieval call binding the contract method 0x458b3a7c.
//
// Solidity: function call(address[] contracts, bytes[] data) view returns((bool,bytes)[] results)
func (_BalanceScanner *BalanceScannerCaller) Call0(opts *bind.CallOpts, contracts []common.Address, data [][]byte) ([]BalanceScannerResult, error) {
var out []interface{}
err := _BalanceScanner.contract.Call(opts, &out, "call0", contracts, data)
if err != nil {
return *new([]BalanceScannerResult), err
}
out0 := *abi.ConvertType(out[0], new([]BalanceScannerResult)).(*[]BalanceScannerResult)
return out0, err
}
// Call0 is a free data retrieval call binding the contract method 0x458b3a7c.
//
// Solidity: function call(address[] contracts, bytes[] data) view returns((bool,bytes)[] results)
func (_BalanceScanner *BalanceScannerSession) Call0(contracts []common.Address, data [][]byte) ([]BalanceScannerResult, error) {
return _BalanceScanner.Contract.Call0(&_BalanceScanner.CallOpts, contracts, data)
}
// Call0 is a free data retrieval call binding the contract method 0x458b3a7c.
//
// Solidity: function call(address[] contracts, bytes[] data) view returns((bool,bytes)[] results)
func (_BalanceScanner *BalanceScannerCallerSession) Call0(contracts []common.Address, data [][]byte) ([]BalanceScannerResult, error) {
return _BalanceScanner.Contract.Call0(&_BalanceScanner.CallOpts, contracts, data)
}
// EtherBalances is a free data retrieval call binding the contract method 0xdbdbb51b.
//
// Solidity: function etherBalances(address[] addresses) view returns((bool,bytes)[] results)
func (_BalanceScanner *BalanceScannerCaller) EtherBalances(opts *bind.CallOpts, addresses []common.Address) ([]BalanceScannerResult, error) {
var out []interface{}
err := _BalanceScanner.contract.Call(opts, &out, "etherBalances", addresses)
if err != nil {
return *new([]BalanceScannerResult), err
}
out0 := *abi.ConvertType(out[0], new([]BalanceScannerResult)).(*[]BalanceScannerResult)
return out0, err
}
// EtherBalances is a free data retrieval call binding the contract method 0xdbdbb51b.
//
// Solidity: function etherBalances(address[] addresses) view returns((bool,bytes)[] results)
func (_BalanceScanner *BalanceScannerSession) EtherBalances(addresses []common.Address) ([]BalanceScannerResult, error) {
return _BalanceScanner.Contract.EtherBalances(&_BalanceScanner.CallOpts, addresses)
}
// EtherBalances is a free data retrieval call binding the contract method 0xdbdbb51b.
//
// Solidity: function etherBalances(address[] addresses) view returns((bool,bytes)[] results)
func (_BalanceScanner *BalanceScannerCallerSession) EtherBalances(addresses []common.Address) ([]BalanceScannerResult, error) {
return _BalanceScanner.Contract.EtherBalances(&_BalanceScanner.CallOpts, addresses)
}
// TokenBalances is a free data retrieval call binding the contract method 0xaad33091.
//
// Solidity: function tokenBalances(address[] addresses, address token) view returns((bool,bytes)[] results)
func (_BalanceScanner *BalanceScannerCaller) TokenBalances(opts *bind.CallOpts, addresses []common.Address, token common.Address) ([]BalanceScannerResult, error) {
var out []interface{}
err := _BalanceScanner.contract.Call(opts, &out, "tokenBalances", addresses, token)
if err != nil {
return *new([]BalanceScannerResult), err
}
out0 := *abi.ConvertType(out[0], new([]BalanceScannerResult)).(*[]BalanceScannerResult)
return out0, err
}
// TokenBalances is a free data retrieval call binding the contract method 0xaad33091.
//
// Solidity: function tokenBalances(address[] addresses, address token) view returns((bool,bytes)[] results)
func (_BalanceScanner *BalanceScannerSession) TokenBalances(addresses []common.Address, token common.Address) ([]BalanceScannerResult, error) {
return _BalanceScanner.Contract.TokenBalances(&_BalanceScanner.CallOpts, addresses, token)
}
// TokenBalances is a free data retrieval call binding the contract method 0xaad33091.
//
// Solidity: function tokenBalances(address[] addresses, address token) view returns((bool,bytes)[] results)
func (_BalanceScanner *BalanceScannerCallerSession) TokenBalances(addresses []common.Address, token common.Address) ([]BalanceScannerResult, error) {
return _BalanceScanner.Contract.TokenBalances(&_BalanceScanner.CallOpts, addresses, token)
}
// TokensBalance is a free data retrieval call binding the contract method 0xe5da1b68.
//
// Solidity: function tokensBalance(address owner, address[] contracts) view returns((bool,bytes)[] results)
func (_BalanceScanner *BalanceScannerCaller) TokensBalance(opts *bind.CallOpts, owner common.Address, contracts []common.Address) ([]BalanceScannerResult, error) {
var out []interface{}
err := _BalanceScanner.contract.Call(opts, &out, "tokensBalance", owner, contracts)
if err != nil {
return *new([]BalanceScannerResult), err
}
out0 := *abi.ConvertType(out[0], new([]BalanceScannerResult)).(*[]BalanceScannerResult)
return out0, err
}
// TokensBalance is a free data retrieval call binding the contract method 0xe5da1b68.
//
// Solidity: function tokensBalance(address owner, address[] contracts) view returns((bool,bytes)[] results)
func (_BalanceScanner *BalanceScannerSession) TokensBalance(owner common.Address, contracts []common.Address) ([]BalanceScannerResult, error) {
return _BalanceScanner.Contract.TokensBalance(&_BalanceScanner.CallOpts, owner, contracts)
}
// TokensBalance is a free data retrieval call binding the contract method 0xe5da1b68.
//
// Solidity: function tokensBalance(address owner, address[] contracts) view returns((bool,bytes)[] results)
func (_BalanceScanner *BalanceScannerCallerSession) TokensBalance(owner common.Address, contracts []common.Address) ([]BalanceScannerResult, error) {
return _BalanceScanner.Contract.TokensBalance(&_BalanceScanner.CallOpts, owner, contracts)
}

View File

@@ -0,0 +1,64 @@
/**
*Submitted for verification at Etherscan.io on 2021-04-07
*/
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;
/**
* @title An Ether or token balance scanner
* @author Maarten Zuidhoorn
* @author Luit Hollander
*/
abstract contract BalanceScanner {
struct Result {
bool success;
bytes data;
}
/**
* @notice Get the Ether balance for all addresses specified
* @param addresses The addresses to get the Ether balance for
* @return results The Ether balance for all addresses in the same order as specified
*/
function etherBalances(address[] calldata addresses) external virtual view returns (Result[] memory results);
/**
* @notice Get the ERC-20 token balance of `token` for all addresses specified
* @dev This does not check if the `token` address specified is actually an ERC-20 token
* @param addresses The addresses to get the token balance for
* @param token The address of the ERC-20 token contract
* @return results The token balance for all addresses in the same order as specified
*/
function tokenBalances(address[] calldata addresses, address token) external virtual view returns (Result[] memory results);
/**
* @notice Get the ERC-20 token balance from multiple contracts for a single owner
* @param owner The address of the token owner
* @param contracts The addresses of the ERC-20 token contracts
* @return results The token balances in the same order as the addresses specified
*/
function tokensBalance(address owner, address[] calldata contracts) external virtual view returns (Result[] memory results);
/**
* @notice Call multiple contracts with the provided arbitrary data
* @param contracts The contracts to call
* @param data The data to call the contracts with
* @return results The raw result of the contract calls
*/
function call(address[] calldata contracts, bytes[] calldata data) external virtual view returns (Result[] memory results);
/**
* @notice Call multiple contracts with the provided arbitrary data
* @param contracts The contracts to call
* @param data The data to call the contracts with
* @param gas The amount of gas to call the contracts with
* @return results The raw result of the contract calls
*/
function call(
address[] calldata contracts,
bytes[] calldata data,
uint256 gas
) public view virtual returns (Result[] memory results);
}

View File

@@ -0,0 +1,115 @@
package hop
import (
"errors"
"github.com/ethereum/go-ethereum/common"
)
var errorNotAvailableOnChainID = errors.New("not available for chainID")
var l2SaddleSwapContractAddresses = map[uint64]map[string]common.Address{
10: {
"USDC": common.HexToAddress("0x3c0FFAca566fCcfD9Cc95139FEF6CBA143795963"),
"USDT": common.HexToAddress("0xeC4B41Af04cF917b54AEb6Df58c0f8D78895b5Ef"),
"DAI": common.HexToAddress("0xF181eD90D6CfaC84B8073FdEA6D34Aa744B41810"),
"ETH": common.HexToAddress("0xaa30D6bba6285d0585722e2440Ff89E23EF68864"),
"WBTC": common.HexToAddress("0x46fc3Af3A47792cA3ED06fdF3D657145A675a8D8"),
},
42161: {
"USDC": common.HexToAddress("0x10541b07d8Ad2647Dc6cD67abd4c03575dade261"),
"USDT": common.HexToAddress("0x18f7402B673Ba6Fb5EA4B95768aABb8aaD7ef18a"),
"DAI": common.HexToAddress("0xa5A33aB9063395A90CCbEa2D86a62EcCf27B5742"),
"ETH": common.HexToAddress("0x652d27c0F72771Ce5C76fd400edD61B406Ac6D97"),
"WBTC": common.HexToAddress("0x7191061D5d4C60f598214cC6913502184BAddf18"),
},
420: {
"USDC": common.HexToAddress("0xE4757dD81AFbecF61E51824AB9238df6691c3D0e"),
"ETH": common.HexToAddress("0xa50395bdEaca7062255109fedE012eFE63d6D402"),
},
421613: {
"USDC": common.HexToAddress("0x83f6244Bd87662118d96D9a6D44f09dffF14b30E"),
"ETH": common.HexToAddress("0x69a71b7F6Ff088a0310b4f911b4f9eA11e2E9740"),
},
}
var l2AmmWrapperContractAddress = map[uint64]map[string]common.Address{
10: {
"USDC": common.HexToAddress("0x2ad09850b0CA4c7c1B33f5AcD6cBAbCaB5d6e796"),
"USDT": common.HexToAddress("0x7D269D3E0d61A05a0bA976b7DBF8805bF844AF3F"),
"DAI": common.HexToAddress("0xb3C68a491608952Cb1257FC9909a537a0173b63B"),
"ETH": common.HexToAddress("0x86cA30bEF97fB651b8d866D45503684b90cb3312"),
"WBTC": common.HexToAddress("0x2A11a98e2fCF4674F30934B5166645fE6CA35F56"),
},
42161: {
"USDC": common.HexToAddress("0xe22D2beDb3Eca35E6397e0C6D62857094aA26F52"),
"USDT": common.HexToAddress("0xCB0a4177E0A60247C0ad18Be87f8eDfF6DD30283"),
"DAI": common.HexToAddress("0xe7F40BF16AB09f4a6906Ac2CAA4094aD2dA48Cc2"),
"ETH": common.HexToAddress("0x33ceb27b39d2Bb7D2e61F7564d3Df29344020417"),
"WBTC": common.HexToAddress("0xC08055b634D43F2176d721E26A3428D3b7E7DdB5"),
},
420: {
"USDC": common.HexToAddress("0xfF21e82a4Bc305BCE591530A68628192b5b6B6FD"),
"ETH": common.HexToAddress("0xC1985d7a3429cDC85E59E2E4Fcc805b857e6Ee2E"),
},
421613: {
"USDC": common.HexToAddress("0x32219766597DFbb10297127238D921E7CCF5D920"),
"ETH": common.HexToAddress("0xa832293f2DCe2f092182F17dd873ae06AD5fDbaF"),
},
}
var l1BridgeContractAddress = map[uint64]map[string]common.Address{
1: {
"USDC": common.HexToAddress("0x3666f603Cc164936C1b87e207F36BEBa4AC5f18a"),
"USDT": common.HexToAddress("0x3666f603Cc164936C1b87e207F36BEBa4AC5f18a"),
"DAI": common.HexToAddress("0x3d4Cc8A61c7528Fd86C55cfe061a78dCBA48EDd1"),
"ETH": common.HexToAddress("0xb8901acB165ed027E32754E0FFe830802919727f"),
"WBTC": common.HexToAddress("0xb98454270065A31D71Bf635F6F7Ee6A518dFb849"),
},
5: {
"USDC": common.HexToAddress("0x7D269D3E0d61A05a0bA976b7DBF8805bF844AF3F"),
"ETH": common.HexToAddress("0xC8A4FB931e8D77df8497790381CA7d228E68a41b"),
},
}
func L2SaddleSwapContractAddress(chainID uint64, symbol string) (common.Address, error) {
tokens, exists := l2SaddleSwapContractAddresses[chainID]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
addr, exists := tokens[symbol]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
return addr, nil
}
func L2AmmWrapperContractAddress(chainID uint64, symbol string) (common.Address, error) {
tokens, exists := l2AmmWrapperContractAddress[chainID]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
addr, exists := tokens[symbol]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
return addr, nil
}
func L1BridgeContractAddress(chainID uint64, symbol string) (common.Address, error) {
tokens, exists := l1BridgeContractAddress[chainID]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
addr, exists := tokens[symbol]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
return addr, nil
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,5 @@
package hop
//go:generate abigen --abi l2SaddleSwap.abi --pkg hopSwap --out swap/l2SaddleSwap.go
//go:generate abigen --abi l1Bridge.abi --pkg hopBridge --out bridge/l1Bridge.go
//go:generate abigen --abi l2AmmWrapper.abi --pkg hopWrapper --out wrapper/l2AmmWrapper.go

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
[{"inputs":[{"internalType":"contract L2_Bridge","name":"_bridge","type":"address"},{"internalType":"contract IERC20","name":"_l2CanonicalToken","type":"address"},{"internalType":"bool","name":"_l2CanonicalTokenIsEth","type":"bool"},{"internalType":"contract IERC20","name":"_hToken","type":"address"},{"internalType":"contract Swap","name":"_exchangeAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"attemptSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bridge","outputs":[{"internalType":"contract L2_Bridge","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exchangeAddress","outputs":[{"internalType":"contract Swap","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2CanonicalToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"l2CanonicalTokenIsEth","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"bonderFee","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"destinationAmountOutMin","type":"uint256"},{"internalType":"uint256","name":"destinationDeadline","type":"uint256"}],"name":"swapAndSend","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,390 @@
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package hopWrapper
import (
"math/big"
"strings"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
)
// Reference imports to suppress errors if they are not otherwise used.
var (
_ = big.NewInt
_ = strings.NewReader
_ = ethereum.NotFound
_ = bind.Bind
_ = common.Big1
_ = types.BloomLookup
_ = event.NewSubscription
)
// HopWrapperABI is the input ABI used to generate the binding from.
const HopWrapperABI = "[{\"inputs\":[{\"internalType\":\"contractL2_Bridge\",\"name\":\"_bridge\",\"type\":\"address\"},{\"internalType\":\"contractIERC20\",\"name\":\"_l2CanonicalToken\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_l2CanonicalTokenIsEth\",\"type\":\"bool\"},{\"internalType\":\"contractIERC20\",\"name\":\"_hToken\",\"type\":\"address\"},{\"internalType\":\"contractSwap\",\"name\":\"_exchangeAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOutMin\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"}],\"name\":\"attemptSwap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridge\",\"outputs\":[{\"internalType\":\"contractL2_Bridge\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"exchangeAddress\",\"outputs\":[{\"internalType\":\"contractSwap\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"hToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2CanonicalToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"l2CanonicalTokenIsEth\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"chainId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"bonderFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amountOutMin\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"destinationAmountOutMin\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"destinationDeadline\",\"type\":\"uint256\"}],\"name\":\"swapAndSend\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]"
// HopWrapper is an auto generated Go binding around an Ethereum contract.
type HopWrapper struct {
HopWrapperCaller // Read-only binding to the contract
HopWrapperTransactor // Write-only binding to the contract
HopWrapperFilterer // Log filterer for contract events
}
// HopWrapperCaller is an auto generated read-only Go binding around an Ethereum contract.
type HopWrapperCaller struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// HopWrapperTransactor is an auto generated write-only Go binding around an Ethereum contract.
type HopWrapperTransactor struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// HopWrapperFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
type HopWrapperFilterer struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// HopWrapperSession is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type HopWrapperSession struct {
Contract *HopWrapper // Generic contract binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// HopWrapperCallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type HopWrapperCallerSession struct {
Contract *HopWrapperCaller // Generic contract caller binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
}
// HopWrapperTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type HopWrapperTransactorSession struct {
Contract *HopWrapperTransactor // Generic contract transactor binding to set the session for
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// HopWrapperRaw is an auto generated low-level Go binding around an Ethereum contract.
type HopWrapperRaw struct {
Contract *HopWrapper // Generic contract binding to access the raw methods on
}
// HopWrapperCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type HopWrapperCallerRaw struct {
Contract *HopWrapperCaller // Generic read-only contract binding to access the raw methods on
}
// HopWrapperTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type HopWrapperTransactorRaw struct {
Contract *HopWrapperTransactor // Generic write-only contract binding to access the raw methods on
}
// NewHopWrapper creates a new instance of HopWrapper, bound to a specific deployed contract.
func NewHopWrapper(address common.Address, backend bind.ContractBackend) (*HopWrapper, error) {
contract, err := bindHopWrapper(address, backend, backend, backend)
if err != nil {
return nil, err
}
return &HopWrapper{HopWrapperCaller: HopWrapperCaller{contract: contract}, HopWrapperTransactor: HopWrapperTransactor{contract: contract}, HopWrapperFilterer: HopWrapperFilterer{contract: contract}}, nil
}
// NewHopWrapperCaller creates a new read-only instance of HopWrapper, bound to a specific deployed contract.
func NewHopWrapperCaller(address common.Address, caller bind.ContractCaller) (*HopWrapperCaller, error) {
contract, err := bindHopWrapper(address, caller, nil, nil)
if err != nil {
return nil, err
}
return &HopWrapperCaller{contract: contract}, nil
}
// NewHopWrapperTransactor creates a new write-only instance of HopWrapper, bound to a specific deployed contract.
func NewHopWrapperTransactor(address common.Address, transactor bind.ContractTransactor) (*HopWrapperTransactor, error) {
contract, err := bindHopWrapper(address, nil, transactor, nil)
if err != nil {
return nil, err
}
return &HopWrapperTransactor{contract: contract}, nil
}
// NewHopWrapperFilterer creates a new log filterer instance of HopWrapper, bound to a specific deployed contract.
func NewHopWrapperFilterer(address common.Address, filterer bind.ContractFilterer) (*HopWrapperFilterer, error) {
contract, err := bindHopWrapper(address, nil, nil, filterer)
if err != nil {
return nil, err
}
return &HopWrapperFilterer{contract: contract}, nil
}
// bindHopWrapper binds a generic wrapper to an already deployed contract.
func bindHopWrapper(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
parsed, err := abi.JSON(strings.NewReader(HopWrapperABI))
if err != nil {
return nil, err
}
return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_HopWrapper *HopWrapperRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _HopWrapper.Contract.HopWrapperCaller.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_HopWrapper *HopWrapperRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _HopWrapper.Contract.HopWrapperTransactor.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_HopWrapper *HopWrapperRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _HopWrapper.Contract.HopWrapperTransactor.contract.Transact(opts, method, params...)
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_HopWrapper *HopWrapperCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _HopWrapper.Contract.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_HopWrapper *HopWrapperTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _HopWrapper.Contract.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_HopWrapper *HopWrapperTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _HopWrapper.Contract.contract.Transact(opts, method, params...)
}
// Bridge is a free data retrieval call binding the contract method 0xe78cea92.
//
// Solidity: function bridge() view returns(address)
func (_HopWrapper *HopWrapperCaller) Bridge(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _HopWrapper.contract.Call(opts, &out, "bridge")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// Bridge is a free data retrieval call binding the contract method 0xe78cea92.
//
// Solidity: function bridge() view returns(address)
func (_HopWrapper *HopWrapperSession) Bridge() (common.Address, error) {
return _HopWrapper.Contract.Bridge(&_HopWrapper.CallOpts)
}
// Bridge is a free data retrieval call binding the contract method 0xe78cea92.
//
// Solidity: function bridge() view returns(address)
func (_HopWrapper *HopWrapperCallerSession) Bridge() (common.Address, error) {
return _HopWrapper.Contract.Bridge(&_HopWrapper.CallOpts)
}
// ExchangeAddress is a free data retrieval call binding the contract method 0x9cd01605.
//
// Solidity: function exchangeAddress() view returns(address)
func (_HopWrapper *HopWrapperCaller) ExchangeAddress(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _HopWrapper.contract.Call(opts, &out, "exchangeAddress")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// ExchangeAddress is a free data retrieval call binding the contract method 0x9cd01605.
//
// Solidity: function exchangeAddress() view returns(address)
func (_HopWrapper *HopWrapperSession) ExchangeAddress() (common.Address, error) {
return _HopWrapper.Contract.ExchangeAddress(&_HopWrapper.CallOpts)
}
// ExchangeAddress is a free data retrieval call binding the contract method 0x9cd01605.
//
// Solidity: function exchangeAddress() view returns(address)
func (_HopWrapper *HopWrapperCallerSession) ExchangeAddress() (common.Address, error) {
return _HopWrapper.Contract.ExchangeAddress(&_HopWrapper.CallOpts)
}
// HToken is a free data retrieval call binding the contract method 0xfc6e3b3b.
//
// Solidity: function hToken() view returns(address)
func (_HopWrapper *HopWrapperCaller) HToken(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _HopWrapper.contract.Call(opts, &out, "hToken")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// HToken is a free data retrieval call binding the contract method 0xfc6e3b3b.
//
// Solidity: function hToken() view returns(address)
func (_HopWrapper *HopWrapperSession) HToken() (common.Address, error) {
return _HopWrapper.Contract.HToken(&_HopWrapper.CallOpts)
}
// HToken is a free data retrieval call binding the contract method 0xfc6e3b3b.
//
// Solidity: function hToken() view returns(address)
func (_HopWrapper *HopWrapperCallerSession) HToken() (common.Address, error) {
return _HopWrapper.Contract.HToken(&_HopWrapper.CallOpts)
}
// L2CanonicalToken is a free data retrieval call binding the contract method 0x1ee1bf67.
//
// Solidity: function l2CanonicalToken() view returns(address)
func (_HopWrapper *HopWrapperCaller) L2CanonicalToken(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _HopWrapper.contract.Call(opts, &out, "l2CanonicalToken")
if err != nil {
return *new(common.Address), err
}
out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address)
return out0, err
}
// L2CanonicalToken is a free data retrieval call binding the contract method 0x1ee1bf67.
//
// Solidity: function l2CanonicalToken() view returns(address)
func (_HopWrapper *HopWrapperSession) L2CanonicalToken() (common.Address, error) {
return _HopWrapper.Contract.L2CanonicalToken(&_HopWrapper.CallOpts)
}
// L2CanonicalToken is a free data retrieval call binding the contract method 0x1ee1bf67.
//
// Solidity: function l2CanonicalToken() view returns(address)
func (_HopWrapper *HopWrapperCallerSession) L2CanonicalToken() (common.Address, error) {
return _HopWrapper.Contract.L2CanonicalToken(&_HopWrapper.CallOpts)
}
// L2CanonicalTokenIsEth is a free data retrieval call binding the contract method 0x28555125.
//
// Solidity: function l2CanonicalTokenIsEth() view returns(bool)
func (_HopWrapper *HopWrapperCaller) L2CanonicalTokenIsEth(opts *bind.CallOpts) (bool, error) {
var out []interface{}
err := _HopWrapper.contract.Call(opts, &out, "l2CanonicalTokenIsEth")
if err != nil {
return *new(bool), err
}
out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
return out0, err
}
// L2CanonicalTokenIsEth is a free data retrieval call binding the contract method 0x28555125.
//
// Solidity: function l2CanonicalTokenIsEth() view returns(bool)
func (_HopWrapper *HopWrapperSession) L2CanonicalTokenIsEth() (bool, error) {
return _HopWrapper.Contract.L2CanonicalTokenIsEth(&_HopWrapper.CallOpts)
}
// L2CanonicalTokenIsEth is a free data retrieval call binding the contract method 0x28555125.
//
// Solidity: function l2CanonicalTokenIsEth() view returns(bool)
func (_HopWrapper *HopWrapperCallerSession) L2CanonicalTokenIsEth() (bool, error) {
return _HopWrapper.Contract.L2CanonicalTokenIsEth(&_HopWrapper.CallOpts)
}
// AttemptSwap is a paid mutator transaction binding the contract method 0x676c5ef6.
//
// Solidity: function attemptSwap(address recipient, uint256 amount, uint256 amountOutMin, uint256 deadline) returns()
func (_HopWrapper *HopWrapperTransactor) AttemptSwap(opts *bind.TransactOpts, recipient common.Address, amount *big.Int, amountOutMin *big.Int, deadline *big.Int) (*types.Transaction, error) {
return _HopWrapper.contract.Transact(opts, "attemptSwap", recipient, amount, amountOutMin, deadline)
}
// AttemptSwap is a paid mutator transaction binding the contract method 0x676c5ef6.
//
// Solidity: function attemptSwap(address recipient, uint256 amount, uint256 amountOutMin, uint256 deadline) returns()
func (_HopWrapper *HopWrapperSession) AttemptSwap(recipient common.Address, amount *big.Int, amountOutMin *big.Int, deadline *big.Int) (*types.Transaction, error) {
return _HopWrapper.Contract.AttemptSwap(&_HopWrapper.TransactOpts, recipient, amount, amountOutMin, deadline)
}
// AttemptSwap is a paid mutator transaction binding the contract method 0x676c5ef6.
//
// Solidity: function attemptSwap(address recipient, uint256 amount, uint256 amountOutMin, uint256 deadline) returns()
func (_HopWrapper *HopWrapperTransactorSession) AttemptSwap(recipient common.Address, amount *big.Int, amountOutMin *big.Int, deadline *big.Int) (*types.Transaction, error) {
return _HopWrapper.Contract.AttemptSwap(&_HopWrapper.TransactOpts, recipient, amount, amountOutMin, deadline)
}
// SwapAndSend is a paid mutator transaction binding the contract method 0xeea0d7b2.
//
// Solidity: function swapAndSend(uint256 chainId, address recipient, uint256 amount, uint256 bonderFee, uint256 amountOutMin, uint256 deadline, uint256 destinationAmountOutMin, uint256 destinationDeadline) payable returns()
func (_HopWrapper *HopWrapperTransactor) SwapAndSend(opts *bind.TransactOpts, chainId *big.Int, recipient common.Address, amount *big.Int, bonderFee *big.Int, amountOutMin *big.Int, deadline *big.Int, destinationAmountOutMin *big.Int, destinationDeadline *big.Int) (*types.Transaction, error) {
return _HopWrapper.contract.Transact(opts, "swapAndSend", chainId, recipient, amount, bonderFee, amountOutMin, deadline, destinationAmountOutMin, destinationDeadline)
}
// SwapAndSend is a paid mutator transaction binding the contract method 0xeea0d7b2.
//
// Solidity: function swapAndSend(uint256 chainId, address recipient, uint256 amount, uint256 bonderFee, uint256 amountOutMin, uint256 deadline, uint256 destinationAmountOutMin, uint256 destinationDeadline) payable returns()
func (_HopWrapper *HopWrapperSession) SwapAndSend(chainId *big.Int, recipient common.Address, amount *big.Int, bonderFee *big.Int, amountOutMin *big.Int, deadline *big.Int, destinationAmountOutMin *big.Int, destinationDeadline *big.Int) (*types.Transaction, error) {
return _HopWrapper.Contract.SwapAndSend(&_HopWrapper.TransactOpts, chainId, recipient, amount, bonderFee, amountOutMin, deadline, destinationAmountOutMin, destinationDeadline)
}
// SwapAndSend is a paid mutator transaction binding the contract method 0xeea0d7b2.
//
// Solidity: function swapAndSend(uint256 chainId, address recipient, uint256 amount, uint256 bonderFee, uint256 amountOutMin, uint256 deadline, uint256 destinationAmountOutMin, uint256 destinationDeadline) payable returns()
func (_HopWrapper *HopWrapperTransactorSession) SwapAndSend(chainId *big.Int, recipient common.Address, amount *big.Int, bonderFee *big.Int, amountOutMin *big.Int, deadline *big.Int, destinationAmountOutMin *big.Int, destinationDeadline *big.Int) (*types.Transaction, error) {
return _HopWrapper.Contract.SwapAndSend(&_HopWrapper.TransactOpts, chainId, recipient, amount, bonderFee, amountOutMin, deadline, destinationAmountOutMin, destinationDeadline)
}
// Receive is a paid mutator transaction binding the contract receive function.
//
// Solidity: receive() payable returns()
func (_HopWrapper *HopWrapperTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) {
return _HopWrapper.contract.RawTransact(opts, nil) // calldata is disallowed for receive function
}
// Receive is a paid mutator transaction binding the contract receive function.
//
// Solidity: receive() payable returns()
func (_HopWrapper *HopWrapperSession) Receive() (*types.Transaction, error) {
return _HopWrapper.Contract.Receive(&_HopWrapper.TransactOpts)
}
// Receive is a paid mutator transaction binding the contract receive function.
//
// Solidity: receive() payable returns()
func (_HopWrapper *HopWrapperTransactorSession) Receive() (*types.Transaction, error) {
return _HopWrapper.Contract.Receive(&_HopWrapper.TransactOpts)
}

View File

@@ -0,0 +1 @@
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":false,"internalType":"bool","name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"_values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_value","type":"string"},{"indexed":true,"internalType":"uint256","name":"_id","type":"uint256"}],"name":"URI","type":"event"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address[]","name":"_owners","type":"address[]"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_values","type":"uint256[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

View File

@@ -0,0 +1,3 @@
package ierc1155
//go:generate abigen -abi ./ERC1155.abi -pkg ierc1155 -out ierc1155.go

View File

@@ -0,0 +1,964 @@
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package ierc1155
import (
"errors"
"math/big"
"strings"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
)
// Reference imports to suppress errors if they are not otherwise used.
var (
_ = errors.New
_ = big.NewInt
_ = strings.NewReader
_ = ethereum.NotFound
_ = bind.Bind
_ = common.Big1
_ = types.BloomLookup
_ = event.NewSubscription
_ = abi.ConvertType
)
// Ierc1155MetaData contains all meta data concerning the Ierc1155 contract.
var Ierc1155MetaData = &bind.MetaData{
ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_operator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_approved\",\"type\":\"bool\"}],\"name\":\"ApprovalForAll\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_values\",\"type\":\"uint256[]\"}],\"name\":\"TransferBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"TransferSingle\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_value\",\"type\":\"string\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"URI\",\"type\":\"event\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_owners\",\"type\":\"address[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"}],\"name\":\"balanceOfBatch\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_operator\",\"type\":\"address\"}],\"name\":\"isApprovedForAll\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256[]\",\"name\":\"_ids\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256[]\",\"name\":\"_values\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"safeBatchTransferFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"safeTransferFrom\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"address\",\"name\":\"_operator\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"_approved\",\"type\":\"bool\"}],\"name\":\"setApprovalForAll\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
}
// Ierc1155ABI is the input ABI used to generate the binding from.
// Deprecated: Use Ierc1155MetaData.ABI instead.
var Ierc1155ABI = Ierc1155MetaData.ABI
// Ierc1155 is an auto generated Go binding around an Ethereum contract.
type Ierc1155 struct {
Ierc1155Caller // Read-only binding to the contract
Ierc1155Transactor // Write-only binding to the contract
Ierc1155Filterer // Log filterer for contract events
}
// Ierc1155Caller is an auto generated read-only Go binding around an Ethereum contract.
type Ierc1155Caller struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// Ierc1155Transactor is an auto generated write-only Go binding around an Ethereum contract.
type Ierc1155Transactor struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// Ierc1155Filterer is an auto generated log filtering Go binding around an Ethereum contract events.
type Ierc1155Filterer struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// Ierc1155Session is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type Ierc1155Session struct {
Contract *Ierc1155 // Generic contract binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// Ierc1155CallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type Ierc1155CallerSession struct {
Contract *Ierc1155Caller // Generic contract caller binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
}
// Ierc1155TransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type Ierc1155TransactorSession struct {
Contract *Ierc1155Transactor // Generic contract transactor binding to set the session for
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// Ierc1155Raw is an auto generated low-level Go binding around an Ethereum contract.
type Ierc1155Raw struct {
Contract *Ierc1155 // Generic contract binding to access the raw methods on
}
// Ierc1155CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type Ierc1155CallerRaw struct {
Contract *Ierc1155Caller // Generic read-only contract binding to access the raw methods on
}
// Ierc1155TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type Ierc1155TransactorRaw struct {
Contract *Ierc1155Transactor // Generic write-only contract binding to access the raw methods on
}
// NewIerc1155 creates a new instance of Ierc1155, bound to a specific deployed contract.
func NewIerc1155(address common.Address, backend bind.ContractBackend) (*Ierc1155, error) {
contract, err := bindIerc1155(address, backend, backend, backend)
if err != nil {
return nil, err
}
return &Ierc1155{Ierc1155Caller: Ierc1155Caller{contract: contract}, Ierc1155Transactor: Ierc1155Transactor{contract: contract}, Ierc1155Filterer: Ierc1155Filterer{contract: contract}}, nil
}
// NewIerc1155Caller creates a new read-only instance of Ierc1155, bound to a specific deployed contract.
func NewIerc1155Caller(address common.Address, caller bind.ContractCaller) (*Ierc1155Caller, error) {
contract, err := bindIerc1155(address, caller, nil, nil)
if err != nil {
return nil, err
}
return &Ierc1155Caller{contract: contract}, nil
}
// NewIerc1155Transactor creates a new write-only instance of Ierc1155, bound to a specific deployed contract.
func NewIerc1155Transactor(address common.Address, transactor bind.ContractTransactor) (*Ierc1155Transactor, error) {
contract, err := bindIerc1155(address, nil, transactor, nil)
if err != nil {
return nil, err
}
return &Ierc1155Transactor{contract: contract}, nil
}
// NewIerc1155Filterer creates a new log filterer instance of Ierc1155, bound to a specific deployed contract.
func NewIerc1155Filterer(address common.Address, filterer bind.ContractFilterer) (*Ierc1155Filterer, error) {
contract, err := bindIerc1155(address, nil, nil, filterer)
if err != nil {
return nil, err
}
return &Ierc1155Filterer{contract: contract}, nil
}
// bindIerc1155 binds a generic wrapper to an already deployed contract.
func bindIerc1155(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
parsed, err := Ierc1155MetaData.GetAbi()
if err != nil {
return nil, err
}
return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_Ierc1155 *Ierc1155Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _Ierc1155.Contract.Ierc1155Caller.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_Ierc1155 *Ierc1155Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _Ierc1155.Contract.Ierc1155Transactor.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_Ierc1155 *Ierc1155Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _Ierc1155.Contract.Ierc1155Transactor.contract.Transact(opts, method, params...)
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_Ierc1155 *Ierc1155CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _Ierc1155.Contract.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_Ierc1155 *Ierc1155TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _Ierc1155.Contract.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_Ierc1155 *Ierc1155TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _Ierc1155.Contract.contract.Transact(opts, method, params...)
}
// BalanceOf is a free data retrieval call binding the contract method 0x00fdd58e.
//
// Solidity: function balanceOf(address _owner, uint256 _id) view returns(uint256)
func (_Ierc1155 *Ierc1155Caller) BalanceOf(opts *bind.CallOpts, _owner common.Address, _id *big.Int) (*big.Int, error) {
var out []interface{}
err := _Ierc1155.contract.Call(opts, &out, "balanceOf", _owner, _id)
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// BalanceOf is a free data retrieval call binding the contract method 0x00fdd58e.
//
// Solidity: function balanceOf(address _owner, uint256 _id) view returns(uint256)
func (_Ierc1155 *Ierc1155Session) BalanceOf(_owner common.Address, _id *big.Int) (*big.Int, error) {
return _Ierc1155.Contract.BalanceOf(&_Ierc1155.CallOpts, _owner, _id)
}
// BalanceOf is a free data retrieval call binding the contract method 0x00fdd58e.
//
// Solidity: function balanceOf(address _owner, uint256 _id) view returns(uint256)
func (_Ierc1155 *Ierc1155CallerSession) BalanceOf(_owner common.Address, _id *big.Int) (*big.Int, error) {
return _Ierc1155.Contract.BalanceOf(&_Ierc1155.CallOpts, _owner, _id)
}
// BalanceOfBatch is a free data retrieval call binding the contract method 0x4e1273f4.
//
// Solidity: function balanceOfBatch(address[] _owners, uint256[] _ids) view returns(uint256[])
func (_Ierc1155 *Ierc1155Caller) BalanceOfBatch(opts *bind.CallOpts, _owners []common.Address, _ids []*big.Int) ([]*big.Int, error) {
var out []interface{}
err := _Ierc1155.contract.Call(opts, &out, "balanceOfBatch", _owners, _ids)
if err != nil {
return *new([]*big.Int), err
}
out0 := *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int)
return out0, err
}
// BalanceOfBatch is a free data retrieval call binding the contract method 0x4e1273f4.
//
// Solidity: function balanceOfBatch(address[] _owners, uint256[] _ids) view returns(uint256[])
func (_Ierc1155 *Ierc1155Session) BalanceOfBatch(_owners []common.Address, _ids []*big.Int) ([]*big.Int, error) {
return _Ierc1155.Contract.BalanceOfBatch(&_Ierc1155.CallOpts, _owners, _ids)
}
// BalanceOfBatch is a free data retrieval call binding the contract method 0x4e1273f4.
//
// Solidity: function balanceOfBatch(address[] _owners, uint256[] _ids) view returns(uint256[])
func (_Ierc1155 *Ierc1155CallerSession) BalanceOfBatch(_owners []common.Address, _ids []*big.Int) ([]*big.Int, error) {
return _Ierc1155.Contract.BalanceOfBatch(&_Ierc1155.CallOpts, _owners, _ids)
}
// IsApprovedForAll is a free data retrieval call binding the contract method 0xe985e9c5.
//
// Solidity: function isApprovedForAll(address _owner, address _operator) view returns(bool)
func (_Ierc1155 *Ierc1155Caller) IsApprovedForAll(opts *bind.CallOpts, _owner common.Address, _operator common.Address) (bool, error) {
var out []interface{}
err := _Ierc1155.contract.Call(opts, &out, "isApprovedForAll", _owner, _operator)
if err != nil {
return *new(bool), err
}
out0 := *abi.ConvertType(out[0], new(bool)).(*bool)
return out0, err
}
// IsApprovedForAll is a free data retrieval call binding the contract method 0xe985e9c5.
//
// Solidity: function isApprovedForAll(address _owner, address _operator) view returns(bool)
func (_Ierc1155 *Ierc1155Session) IsApprovedForAll(_owner common.Address, _operator common.Address) (bool, error) {
return _Ierc1155.Contract.IsApprovedForAll(&_Ierc1155.CallOpts, _owner, _operator)
}
// IsApprovedForAll is a free data retrieval call binding the contract method 0xe985e9c5.
//
// Solidity: function isApprovedForAll(address _owner, address _operator) view returns(bool)
func (_Ierc1155 *Ierc1155CallerSession) IsApprovedForAll(_owner common.Address, _operator common.Address) (bool, error) {
return _Ierc1155.Contract.IsApprovedForAll(&_Ierc1155.CallOpts, _owner, _operator)
}
// SafeBatchTransferFrom is a paid mutator transaction binding the contract method 0x2eb2c2d6.
//
// Solidity: function safeBatchTransferFrom(address _from, address _to, uint256[] _ids, uint256[] _values, bytes _data) returns()
func (_Ierc1155 *Ierc1155Transactor) SafeBatchTransferFrom(opts *bind.TransactOpts, _from common.Address, _to common.Address, _ids []*big.Int, _values []*big.Int, _data []byte) (*types.Transaction, error) {
return _Ierc1155.contract.Transact(opts, "safeBatchTransferFrom", _from, _to, _ids, _values, _data)
}
// SafeBatchTransferFrom is a paid mutator transaction binding the contract method 0x2eb2c2d6.
//
// Solidity: function safeBatchTransferFrom(address _from, address _to, uint256[] _ids, uint256[] _values, bytes _data) returns()
func (_Ierc1155 *Ierc1155Session) SafeBatchTransferFrom(_from common.Address, _to common.Address, _ids []*big.Int, _values []*big.Int, _data []byte) (*types.Transaction, error) {
return _Ierc1155.Contract.SafeBatchTransferFrom(&_Ierc1155.TransactOpts, _from, _to, _ids, _values, _data)
}
// SafeBatchTransferFrom is a paid mutator transaction binding the contract method 0x2eb2c2d6.
//
// Solidity: function safeBatchTransferFrom(address _from, address _to, uint256[] _ids, uint256[] _values, bytes _data) returns()
func (_Ierc1155 *Ierc1155TransactorSession) SafeBatchTransferFrom(_from common.Address, _to common.Address, _ids []*big.Int, _values []*big.Int, _data []byte) (*types.Transaction, error) {
return _Ierc1155.Contract.SafeBatchTransferFrom(&_Ierc1155.TransactOpts, _from, _to, _ids, _values, _data)
}
// SafeTransferFrom is a paid mutator transaction binding the contract method 0xf242432a.
//
// Solidity: function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes _data) returns()
func (_Ierc1155 *Ierc1155Transactor) SafeTransferFrom(opts *bind.TransactOpts, _from common.Address, _to common.Address, _id *big.Int, _value *big.Int, _data []byte) (*types.Transaction, error) {
return _Ierc1155.contract.Transact(opts, "safeTransferFrom", _from, _to, _id, _value, _data)
}
// SafeTransferFrom is a paid mutator transaction binding the contract method 0xf242432a.
//
// Solidity: function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes _data) returns()
func (_Ierc1155 *Ierc1155Session) SafeTransferFrom(_from common.Address, _to common.Address, _id *big.Int, _value *big.Int, _data []byte) (*types.Transaction, error) {
return _Ierc1155.Contract.SafeTransferFrom(&_Ierc1155.TransactOpts, _from, _to, _id, _value, _data)
}
// SafeTransferFrom is a paid mutator transaction binding the contract method 0xf242432a.
//
// Solidity: function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes _data) returns()
func (_Ierc1155 *Ierc1155TransactorSession) SafeTransferFrom(_from common.Address, _to common.Address, _id *big.Int, _value *big.Int, _data []byte) (*types.Transaction, error) {
return _Ierc1155.Contract.SafeTransferFrom(&_Ierc1155.TransactOpts, _from, _to, _id, _value, _data)
}
// SetApprovalForAll is a paid mutator transaction binding the contract method 0xa22cb465.
//
// Solidity: function setApprovalForAll(address _operator, bool _approved) returns()
func (_Ierc1155 *Ierc1155Transactor) SetApprovalForAll(opts *bind.TransactOpts, _operator common.Address, _approved bool) (*types.Transaction, error) {
return _Ierc1155.contract.Transact(opts, "setApprovalForAll", _operator, _approved)
}
// SetApprovalForAll is a paid mutator transaction binding the contract method 0xa22cb465.
//
// Solidity: function setApprovalForAll(address _operator, bool _approved) returns()
func (_Ierc1155 *Ierc1155Session) SetApprovalForAll(_operator common.Address, _approved bool) (*types.Transaction, error) {
return _Ierc1155.Contract.SetApprovalForAll(&_Ierc1155.TransactOpts, _operator, _approved)
}
// SetApprovalForAll is a paid mutator transaction binding the contract method 0xa22cb465.
//
// Solidity: function setApprovalForAll(address _operator, bool _approved) returns()
func (_Ierc1155 *Ierc1155TransactorSession) SetApprovalForAll(_operator common.Address, _approved bool) (*types.Transaction, error) {
return _Ierc1155.Contract.SetApprovalForAll(&_Ierc1155.TransactOpts, _operator, _approved)
}
// Ierc1155ApprovalForAllIterator is returned from FilterApprovalForAll and is used to iterate over the raw logs and unpacked data for ApprovalForAll events raised by the Ierc1155 contract.
type Ierc1155ApprovalForAllIterator struct {
Event *Ierc1155ApprovalForAll // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *Ierc1155ApprovalForAllIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(Ierc1155ApprovalForAll)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(Ierc1155ApprovalForAll)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *Ierc1155ApprovalForAllIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *Ierc1155ApprovalForAllIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// Ierc1155ApprovalForAll represents a ApprovalForAll event raised by the Ierc1155 contract.
type Ierc1155ApprovalForAll struct {
Owner common.Address
Operator common.Address
Approved bool
Raw types.Log // Blockchain specific contextual infos
}
// FilterApprovalForAll is a free log retrieval operation binding the contract event 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31.
//
// Solidity: event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved)
func (_Ierc1155 *Ierc1155Filterer) FilterApprovalForAll(opts *bind.FilterOpts, _owner []common.Address, _operator []common.Address) (*Ierc1155ApprovalForAllIterator, error) {
var _ownerRule []interface{}
for _, _ownerItem := range _owner {
_ownerRule = append(_ownerRule, _ownerItem)
}
var _operatorRule []interface{}
for _, _operatorItem := range _operator {
_operatorRule = append(_operatorRule, _operatorItem)
}
logs, sub, err := _Ierc1155.contract.FilterLogs(opts, "ApprovalForAll", _ownerRule, _operatorRule)
if err != nil {
return nil, err
}
return &Ierc1155ApprovalForAllIterator{contract: _Ierc1155.contract, event: "ApprovalForAll", logs: logs, sub: sub}, nil
}
// WatchApprovalForAll is a free log subscription operation binding the contract event 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31.
//
// Solidity: event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved)
func (_Ierc1155 *Ierc1155Filterer) WatchApprovalForAll(opts *bind.WatchOpts, sink chan<- *Ierc1155ApprovalForAll, _owner []common.Address, _operator []common.Address) (event.Subscription, error) {
var _ownerRule []interface{}
for _, _ownerItem := range _owner {
_ownerRule = append(_ownerRule, _ownerItem)
}
var _operatorRule []interface{}
for _, _operatorItem := range _operator {
_operatorRule = append(_operatorRule, _operatorItem)
}
logs, sub, err := _Ierc1155.contract.WatchLogs(opts, "ApprovalForAll", _ownerRule, _operatorRule)
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(Ierc1155ApprovalForAll)
if err := _Ierc1155.contract.UnpackLog(event, "ApprovalForAll", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseApprovalForAll is a log parse operation binding the contract event 0x17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31.
//
// Solidity: event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved)
func (_Ierc1155 *Ierc1155Filterer) ParseApprovalForAll(log types.Log) (*Ierc1155ApprovalForAll, error) {
event := new(Ierc1155ApprovalForAll)
if err := _Ierc1155.contract.UnpackLog(event, "ApprovalForAll", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// Ierc1155TransferBatchIterator is returned from FilterTransferBatch and is used to iterate over the raw logs and unpacked data for TransferBatch events raised by the Ierc1155 contract.
type Ierc1155TransferBatchIterator struct {
Event *Ierc1155TransferBatch // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *Ierc1155TransferBatchIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(Ierc1155TransferBatch)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(Ierc1155TransferBatch)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *Ierc1155TransferBatchIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *Ierc1155TransferBatchIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// Ierc1155TransferBatch represents a TransferBatch event raised by the Ierc1155 contract.
type Ierc1155TransferBatch struct {
Operator common.Address
From common.Address
To common.Address
Ids []*big.Int
Values []*big.Int
Raw types.Log // Blockchain specific contextual infos
}
// FilterTransferBatch is a free log retrieval operation binding the contract event 0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb.
//
// Solidity: event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values)
func (_Ierc1155 *Ierc1155Filterer) FilterTransferBatch(opts *bind.FilterOpts, _operator []common.Address, _from []common.Address, _to []common.Address) (*Ierc1155TransferBatchIterator, error) {
var _operatorRule []interface{}
for _, _operatorItem := range _operator {
_operatorRule = append(_operatorRule, _operatorItem)
}
var _fromRule []interface{}
for _, _fromItem := range _from {
_fromRule = append(_fromRule, _fromItem)
}
var _toRule []interface{}
for _, _toItem := range _to {
_toRule = append(_toRule, _toItem)
}
logs, sub, err := _Ierc1155.contract.FilterLogs(opts, "TransferBatch", _operatorRule, _fromRule, _toRule)
if err != nil {
return nil, err
}
return &Ierc1155TransferBatchIterator{contract: _Ierc1155.contract, event: "TransferBatch", logs: logs, sub: sub}, nil
}
// WatchTransferBatch is a free log subscription operation binding the contract event 0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb.
//
// Solidity: event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values)
func (_Ierc1155 *Ierc1155Filterer) WatchTransferBatch(opts *bind.WatchOpts, sink chan<- *Ierc1155TransferBatch, _operator []common.Address, _from []common.Address, _to []common.Address) (event.Subscription, error) {
var _operatorRule []interface{}
for _, _operatorItem := range _operator {
_operatorRule = append(_operatorRule, _operatorItem)
}
var _fromRule []interface{}
for _, _fromItem := range _from {
_fromRule = append(_fromRule, _fromItem)
}
var _toRule []interface{}
for _, _toItem := range _to {
_toRule = append(_toRule, _toItem)
}
logs, sub, err := _Ierc1155.contract.WatchLogs(opts, "TransferBatch", _operatorRule, _fromRule, _toRule)
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(Ierc1155TransferBatch)
if err := _Ierc1155.contract.UnpackLog(event, "TransferBatch", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseTransferBatch is a log parse operation binding the contract event 0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb.
//
// Solidity: event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values)
func (_Ierc1155 *Ierc1155Filterer) ParseTransferBatch(log types.Log) (*Ierc1155TransferBatch, error) {
event := new(Ierc1155TransferBatch)
if err := _Ierc1155.contract.UnpackLog(event, "TransferBatch", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// Ierc1155TransferSingleIterator is returned from FilterTransferSingle and is used to iterate over the raw logs and unpacked data for TransferSingle events raised by the Ierc1155 contract.
type Ierc1155TransferSingleIterator struct {
Event *Ierc1155TransferSingle // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *Ierc1155TransferSingleIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(Ierc1155TransferSingle)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(Ierc1155TransferSingle)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *Ierc1155TransferSingleIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *Ierc1155TransferSingleIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// Ierc1155TransferSingle represents a TransferSingle event raised by the Ierc1155 contract.
type Ierc1155TransferSingle struct {
Operator common.Address
From common.Address
To common.Address
Id *big.Int
Value *big.Int
Raw types.Log // Blockchain specific contextual infos
}
// FilterTransferSingle is a free log retrieval operation binding the contract event 0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62.
//
// Solidity: event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value)
func (_Ierc1155 *Ierc1155Filterer) FilterTransferSingle(opts *bind.FilterOpts, _operator []common.Address, _from []common.Address, _to []common.Address) (*Ierc1155TransferSingleIterator, error) {
var _operatorRule []interface{}
for _, _operatorItem := range _operator {
_operatorRule = append(_operatorRule, _operatorItem)
}
var _fromRule []interface{}
for _, _fromItem := range _from {
_fromRule = append(_fromRule, _fromItem)
}
var _toRule []interface{}
for _, _toItem := range _to {
_toRule = append(_toRule, _toItem)
}
logs, sub, err := _Ierc1155.contract.FilterLogs(opts, "TransferSingle", _operatorRule, _fromRule, _toRule)
if err != nil {
return nil, err
}
return &Ierc1155TransferSingleIterator{contract: _Ierc1155.contract, event: "TransferSingle", logs: logs, sub: sub}, nil
}
// WatchTransferSingle is a free log subscription operation binding the contract event 0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62.
//
// Solidity: event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value)
func (_Ierc1155 *Ierc1155Filterer) WatchTransferSingle(opts *bind.WatchOpts, sink chan<- *Ierc1155TransferSingle, _operator []common.Address, _from []common.Address, _to []common.Address) (event.Subscription, error) {
var _operatorRule []interface{}
for _, _operatorItem := range _operator {
_operatorRule = append(_operatorRule, _operatorItem)
}
var _fromRule []interface{}
for _, _fromItem := range _from {
_fromRule = append(_fromRule, _fromItem)
}
var _toRule []interface{}
for _, _toItem := range _to {
_toRule = append(_toRule, _toItem)
}
logs, sub, err := _Ierc1155.contract.WatchLogs(opts, "TransferSingle", _operatorRule, _fromRule, _toRule)
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(Ierc1155TransferSingle)
if err := _Ierc1155.contract.UnpackLog(event, "TransferSingle", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseTransferSingle is a log parse operation binding the contract event 0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62.
//
// Solidity: event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value)
func (_Ierc1155 *Ierc1155Filterer) ParseTransferSingle(log types.Log) (*Ierc1155TransferSingle, error) {
event := new(Ierc1155TransferSingle)
if err := _Ierc1155.contract.UnpackLog(event, "TransferSingle", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// Ierc1155URIIterator is returned from FilterURI and is used to iterate over the raw logs and unpacked data for URI events raised by the Ierc1155 contract.
type Ierc1155URIIterator struct {
Event *Ierc1155URI // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *Ierc1155URIIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(Ierc1155URI)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(Ierc1155URI)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *Ierc1155URIIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *Ierc1155URIIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// Ierc1155URI represents a URI event raised by the Ierc1155 contract.
type Ierc1155URI struct {
Value string
Id *big.Int
Raw types.Log // Blockchain specific contextual infos
}
// FilterURI is a free log retrieval operation binding the contract event 0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b.
//
// Solidity: event URI(string _value, uint256 indexed _id)
func (_Ierc1155 *Ierc1155Filterer) FilterURI(opts *bind.FilterOpts, _id []*big.Int) (*Ierc1155URIIterator, error) {
var _idRule []interface{}
for _, _idItem := range _id {
_idRule = append(_idRule, _idItem)
}
logs, sub, err := _Ierc1155.contract.FilterLogs(opts, "URI", _idRule)
if err != nil {
return nil, err
}
return &Ierc1155URIIterator{contract: _Ierc1155.contract, event: "URI", logs: logs, sub: sub}, nil
}
// WatchURI is a free log subscription operation binding the contract event 0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b.
//
// Solidity: event URI(string _value, uint256 indexed _id)
func (_Ierc1155 *Ierc1155Filterer) WatchURI(opts *bind.WatchOpts, sink chan<- *Ierc1155URI, _id []*big.Int) (event.Subscription, error) {
var _idRule []interface{}
for _, _idItem := range _id {
_idRule = append(_idRule, _idItem)
}
logs, sub, err := _Ierc1155.contract.WatchLogs(opts, "URI", _idRule)
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(Ierc1155URI)
if err := _Ierc1155.contract.UnpackLog(event, "URI", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseURI is a log parse operation binding the contract event 0x6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b.
//
// Solidity: event URI(string _value, uint256 indexed _id)
func (_Ierc1155 *Ierc1155Filterer) ParseURI(log types.Log) (*Ierc1155URI, error) {
event := new(Ierc1155URI)
if err := _Ierc1155.contract.UnpackLog(event, "URI", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}

View File

@@ -0,0 +1,147 @@
pragma solidity ^0.5.16;
/**
@title ERC-1155 Multi Token Standard
@dev See https://eips.ethereum.org/EIPS/eip-1155
Note: The ERC-165 identifier for this interface is 0xd9b67a26.
*/
/* is ERC165 */ interface ERC1155 {
/**
@dev Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard).
The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender).
The `_from` argument MUST be the address of the holder whose balance is decreased.
The `_to` argument MUST be the address of the recipient whose balance is increased.
The `_id` argument MUST be the token type being transferred.
The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by.
When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address).
When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address).
*/
event TransferSingle(
address indexed _operator,
address indexed _from,
address indexed _to,
uint256 _id,
uint256 _value
);
/**
@dev Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard).
The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender).
The `_from` argument MUST be the address of the holder whose balance is decreased.
The `_to` argument MUST be the address of the recipient whose balance is increased.
The `_ids` argument MUST be the list of tokens being transferred.
The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in _ids) the holder balance is decreased by and match what the recipient balance is increased by.
When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address).
When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address).
*/
event TransferBatch(
address indexed _operator,
address indexed _from,
address indexed _to,
uint256[] _ids,
uint256[] _values
);
/**
@dev MUST emit when approval for a second party/operator address to manage all tokens for an owner address is enabled or disabled (absence of an event assumes disabled).
*/
event ApprovalForAll(
address indexed _owner,
address indexed _operator,
bool _approved
);
/**
@dev MUST emit when the URI is updated for a token ID.
URIs are defined in RFC 3986.
The URI MUST point to a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema".
*/
event URI(string _value, uint256 indexed _id);
/**
@notice Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call).
@dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard).
MUST revert if `_to` is the zero address.
MUST revert if balance of holder for token `_id` is lower than the `_value` sent.
MUST revert on any other error.
MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard).
After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
@param _from Source address
@param _to Target address
@param _id ID of the token type
@param _value Transfer amount
@param _data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to`
*/
function safeTransferFrom(
address _from,
address _to,
uint256 _id,
uint256 _value,
bytes calldata _data
) external;
/**
@notice Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call).
@dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard).
MUST revert if `_to` is the zero address.
MUST revert if length of `_ids` is not the same as length of `_values`.
MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient.
MUST revert on any other error.
MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard).
Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc).
After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard).
@param _from Source address
@param _to Target address
@param _ids IDs of each token type (order and length must match _values array)
@param _values Transfer amounts per token type (order and length must match _ids array)
@param _data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to`
*/
function safeBatchTransferFrom(
address _from,
address _to,
uint256[] calldata _ids,
uint256[] calldata _values,
bytes calldata _data
) external;
/**
@notice Get the balance of an account's tokens.
@param _owner The address of the token holder
@param _id ID of the token
@return The _owner's balance of the token type requested
*/
function balanceOf(
address _owner,
uint256 _id
) external view returns (uint256);
/**
@notice Get the balance of multiple account/token pairs
@param _owners The addresses of the token holders
@param _ids ID of the tokens
@return The _owner's balance of the token types requested (i.e. balance for each (owner, id) pair)
*/
function balanceOfBatch(
address[] calldata _owners,
uint256[] calldata _ids
) external view returns (uint256[] memory);
/**
@notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens.
@dev MUST emit the ApprovalForAll event on success.
@param _operator Address to add to the set of authorized operators
@param _approved True if the operator is approved, false to revoke approval
*/
function setApprovalForAll(address _operator, bool _approved) external;
/**
@notice Queries the approval status of an operator for a given owner.
@param _owner The owner of the tokens
@param _operator Address of authorized operator
@return True if the operator is approved, false if not
*/
function isApprovedForAll(
address _owner,
address _operator
) external view returns (bool);
}

View File

@@ -0,0 +1,5 @@
ERC20 interface
===============
Can be used for interaction with any erc20 compatible token.
Code was taken from [zeppelin libraries](https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/IERC20.sol).

View File

@@ -0,0 +1,3 @@
package ierc20
//go:generate abigen -sol ierc20.sol -pkg ierc20 -out ierc20.go

View File

@@ -0,0 +1,742 @@
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package ierc20
import (
"math/big"
"strings"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
)
// Reference imports to suppress errors if they are not otherwise used.
var (
_ = big.NewInt
_ = strings.NewReader
_ = ethereum.NotFound
_ = bind.Bind
_ = common.Big1
_ = types.BloomLookup
_ = event.NewSubscription
)
// IERC20ABI is the input ABI used to generate the binding from.
const IERC20ABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"spender\",\"type\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"sender\",\"type\":\"address\"},{\"name\":\"recipient\",\"type\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"recipient\",\"type\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"}]"
// IERC20FuncSigs maps the 4-byte function signature to its string representation.
var IERC20FuncSigs = map[string]string{
"dd62ed3e": "allowance(address,address)",
"095ea7b3": "approve(address,uint256)",
"70a08231": "balanceOf(address)",
"313ce567": "decimals()",
"06fdde03": "name()",
"95d89b41": "symbol()",
"18160ddd": "totalSupply()",
"a9059cbb": "transfer(address,uint256)",
"23b872dd": "transferFrom(address,address,uint256)",
}
// IERC20 is an auto generated Go binding around an Ethereum contract.
type IERC20 struct {
IERC20Caller // Read-only binding to the contract
IERC20Transactor // Write-only binding to the contract
IERC20Filterer // Log filterer for contract events
}
// IERC20Caller is an auto generated read-only Go binding around an Ethereum contract.
type IERC20Caller struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// IERC20Transactor is an auto generated write-only Go binding around an Ethereum contract.
type IERC20Transactor struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// IERC20Filterer is an auto generated log filtering Go binding around an Ethereum contract events.
type IERC20Filterer struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// IERC20Session is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type IERC20Session struct {
Contract *IERC20 // Generic contract binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// IERC20CallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type IERC20CallerSession struct {
Contract *IERC20Caller // Generic contract caller binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
}
// IERC20TransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type IERC20TransactorSession struct {
Contract *IERC20Transactor // Generic contract transactor binding to set the session for
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// IERC20Raw is an auto generated low-level Go binding around an Ethereum contract.
type IERC20Raw struct {
Contract *IERC20 // Generic contract binding to access the raw methods on
}
// IERC20CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type IERC20CallerRaw struct {
Contract *IERC20Caller // Generic read-only contract binding to access the raw methods on
}
// IERC20TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type IERC20TransactorRaw struct {
Contract *IERC20Transactor // Generic write-only contract binding to access the raw methods on
}
// NewIERC20 creates a new instance of IERC20, bound to a specific deployed contract.
func NewIERC20(address common.Address, backend bind.ContractBackend) (*IERC20, error) {
contract, err := bindIERC20(address, backend, backend, backend)
if err != nil {
return nil, err
}
return &IERC20{IERC20Caller: IERC20Caller{contract: contract}, IERC20Transactor: IERC20Transactor{contract: contract}, IERC20Filterer: IERC20Filterer{contract: contract}}, nil
}
// NewIERC20Caller creates a new read-only instance of IERC20, bound to a specific deployed contract.
func NewIERC20Caller(address common.Address, caller bind.ContractCaller) (*IERC20Caller, error) {
contract, err := bindIERC20(address, caller, nil, nil)
if err != nil {
return nil, err
}
return &IERC20Caller{contract: contract}, nil
}
// NewIERC20Transactor creates a new write-only instance of IERC20, bound to a specific deployed contract.
func NewIERC20Transactor(address common.Address, transactor bind.ContractTransactor) (*IERC20Transactor, error) {
contract, err := bindIERC20(address, nil, transactor, nil)
if err != nil {
return nil, err
}
return &IERC20Transactor{contract: contract}, nil
}
// NewIERC20Filterer creates a new log filterer instance of IERC20, bound to a specific deployed contract.
func NewIERC20Filterer(address common.Address, filterer bind.ContractFilterer) (*IERC20Filterer, error) {
contract, err := bindIERC20(address, nil, nil, filterer)
if err != nil {
return nil, err
}
return &IERC20Filterer{contract: contract}, nil
}
// bindIERC20 binds a generic wrapper to an already deployed contract.
func bindIERC20(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
parsed, err := abi.JSON(strings.NewReader(IERC20ABI))
if err != nil {
return nil, err
}
return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_IERC20 *IERC20Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _IERC20.Contract.IERC20Caller.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_IERC20 *IERC20Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _IERC20.Contract.IERC20Transactor.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_IERC20 *IERC20Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _IERC20.Contract.IERC20Transactor.contract.Transact(opts, method, params...)
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_IERC20 *IERC20CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
return _IERC20.Contract.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_IERC20 *IERC20TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _IERC20.Contract.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_IERC20 *IERC20TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _IERC20.Contract.contract.Transact(opts, method, params...)
}
// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e.
//
// Solidity: function allowance(address owner, address spender) view returns(uint256)
func (_IERC20 *IERC20Caller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) {
var out []interface{}
err := _IERC20.contract.Call(opts, &out, "allowance", owner, spender)
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e.
//
// Solidity: function allowance(address owner, address spender) view returns(uint256)
func (_IERC20 *IERC20Session) Allowance(owner common.Address, spender common.Address) (*big.Int, error) {
return _IERC20.Contract.Allowance(&_IERC20.CallOpts, owner, spender)
}
// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e.
//
// Solidity: function allowance(address owner, address spender) view returns(uint256)
func (_IERC20 *IERC20CallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) {
return _IERC20.Contract.Allowance(&_IERC20.CallOpts, owner, spender)
}
// BalanceOf is a free data retrieval call binding the contract method 0x70a08231.
//
// Solidity: function balanceOf(address account) view returns(uint256)
func (_IERC20 *IERC20Caller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) {
var out []interface{}
err := _IERC20.contract.Call(opts, &out, "balanceOf", account)
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// BalanceOf is a free data retrieval call binding the contract method 0x70a08231.
//
// Solidity: function balanceOf(address account) view returns(uint256)
func (_IERC20 *IERC20Session) BalanceOf(account common.Address) (*big.Int, error) {
return _IERC20.Contract.BalanceOf(&_IERC20.CallOpts, account)
}
// BalanceOf is a free data retrieval call binding the contract method 0x70a08231.
//
// Solidity: function balanceOf(address account) view returns(uint256)
func (_IERC20 *IERC20CallerSession) BalanceOf(account common.Address) (*big.Int, error) {
return _IERC20.Contract.BalanceOf(&_IERC20.CallOpts, account)
}
// Decimals is a free data retrieval call binding the contract method 0x313ce567.
//
// Solidity: function decimals() view returns(uint8)
func (_IERC20 *IERC20Caller) Decimals(opts *bind.CallOpts) (uint8, error) {
var out []interface{}
err := _IERC20.contract.Call(opts, &out, "decimals")
if err != nil {
return *new(uint8), err
}
out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8)
return out0, err
}
// Decimals is a free data retrieval call binding the contract method 0x313ce567.
//
// Solidity: function decimals() view returns(uint8)
func (_IERC20 *IERC20Session) Decimals() (uint8, error) {
return _IERC20.Contract.Decimals(&_IERC20.CallOpts)
}
// Decimals is a free data retrieval call binding the contract method 0x313ce567.
//
// Solidity: function decimals() view returns(uint8)
func (_IERC20 *IERC20CallerSession) Decimals() (uint8, error) {
return _IERC20.Contract.Decimals(&_IERC20.CallOpts)
}
// Name is a free data retrieval call binding the contract method 0x06fdde03.
//
// Solidity: function name() view returns(string)
func (_IERC20 *IERC20Caller) Name(opts *bind.CallOpts) (string, error) {
var out []interface{}
err := _IERC20.contract.Call(opts, &out, "name")
if err != nil {
return *new(string), err
}
out0 := *abi.ConvertType(out[0], new(string)).(*string)
return out0, err
}
// Name is a free data retrieval call binding the contract method 0x06fdde03.
//
// Solidity: function name() view returns(string)
func (_IERC20 *IERC20Session) Name() (string, error) {
return _IERC20.Contract.Name(&_IERC20.CallOpts)
}
// Name is a free data retrieval call binding the contract method 0x06fdde03.
//
// Solidity: function name() view returns(string)
func (_IERC20 *IERC20CallerSession) Name() (string, error) {
return _IERC20.Contract.Name(&_IERC20.CallOpts)
}
// Symbol is a free data retrieval call binding the contract method 0x95d89b41.
//
// Solidity: function symbol() view returns(string)
func (_IERC20 *IERC20Caller) Symbol(opts *bind.CallOpts) (string, error) {
var out []interface{}
err := _IERC20.contract.Call(opts, &out, "symbol")
if err != nil {
return *new(string), err
}
out0 := *abi.ConvertType(out[0], new(string)).(*string)
return out0, err
}
// Symbol is a free data retrieval call binding the contract method 0x95d89b41.
//
// Solidity: function symbol() view returns(string)
func (_IERC20 *IERC20Session) Symbol() (string, error) {
return _IERC20.Contract.Symbol(&_IERC20.CallOpts)
}
// Symbol is a free data retrieval call binding the contract method 0x95d89b41.
//
// Solidity: function symbol() view returns(string)
func (_IERC20 *IERC20CallerSession) Symbol() (string, error) {
return _IERC20.Contract.Symbol(&_IERC20.CallOpts)
}
// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd.
//
// Solidity: function totalSupply() view returns(uint256)
func (_IERC20 *IERC20Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) {
var out []interface{}
err := _IERC20.contract.Call(opts, &out, "totalSupply")
if err != nil {
return *new(*big.Int), err
}
out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)
return out0, err
}
// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd.
//
// Solidity: function totalSupply() view returns(uint256)
func (_IERC20 *IERC20Session) TotalSupply() (*big.Int, error) {
return _IERC20.Contract.TotalSupply(&_IERC20.CallOpts)
}
// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd.
//
// Solidity: function totalSupply() view returns(uint256)
func (_IERC20 *IERC20CallerSession) TotalSupply() (*big.Int, error) {
return _IERC20.Contract.TotalSupply(&_IERC20.CallOpts)
}
// Approve is a paid mutator transaction binding the contract method 0x095ea7b3.
//
// Solidity: function approve(address spender, uint256 amount) returns(bool)
func (_IERC20 *IERC20Transactor) Approve(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) {
return _IERC20.contract.Transact(opts, "approve", spender, amount)
}
// Approve is a paid mutator transaction binding the contract method 0x095ea7b3.
//
// Solidity: function approve(address spender, uint256 amount) returns(bool)
func (_IERC20 *IERC20Session) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) {
return _IERC20.Contract.Approve(&_IERC20.TransactOpts, spender, amount)
}
// Approve is a paid mutator transaction binding the contract method 0x095ea7b3.
//
// Solidity: function approve(address spender, uint256 amount) returns(bool)
func (_IERC20 *IERC20TransactorSession) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) {
return _IERC20.Contract.Approve(&_IERC20.TransactOpts, spender, amount)
}
// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb.
//
// Solidity: function transfer(address recipient, uint256 amount) returns(bool)
func (_IERC20 *IERC20Transactor) Transfer(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) {
return _IERC20.contract.Transact(opts, "transfer", recipient, amount)
}
// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb.
//
// Solidity: function transfer(address recipient, uint256 amount) returns(bool)
func (_IERC20 *IERC20Session) Transfer(recipient common.Address, amount *big.Int) (*types.Transaction, error) {
return _IERC20.Contract.Transfer(&_IERC20.TransactOpts, recipient, amount)
}
// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb.
//
// Solidity: function transfer(address recipient, uint256 amount) returns(bool)
func (_IERC20 *IERC20TransactorSession) Transfer(recipient common.Address, amount *big.Int) (*types.Transaction, error) {
return _IERC20.Contract.Transfer(&_IERC20.TransactOpts, recipient, amount)
}
// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd.
//
// Solidity: function transferFrom(address sender, address recipient, uint256 amount) returns(bool)
func (_IERC20 *IERC20Transactor) TransferFrom(opts *bind.TransactOpts, sender common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) {
return _IERC20.contract.Transact(opts, "transferFrom", sender, recipient, amount)
}
// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd.
//
// Solidity: function transferFrom(address sender, address recipient, uint256 amount) returns(bool)
func (_IERC20 *IERC20Session) TransferFrom(sender common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) {
return _IERC20.Contract.TransferFrom(&_IERC20.TransactOpts, sender, recipient, amount)
}
// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd.
//
// Solidity: function transferFrom(address sender, address recipient, uint256 amount) returns(bool)
func (_IERC20 *IERC20TransactorSession) TransferFrom(sender common.Address, recipient common.Address, amount *big.Int) (*types.Transaction, error) {
return _IERC20.Contract.TransferFrom(&_IERC20.TransactOpts, sender, recipient, amount)
}
// IERC20ApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the IERC20 contract.
type IERC20ApprovalIterator struct {
Event *IERC20Approval // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *IERC20ApprovalIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(IERC20Approval)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(IERC20Approval)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *IERC20ApprovalIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *IERC20ApprovalIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// IERC20Approval represents a Approval event raised by the IERC20 contract.
type IERC20Approval struct {
Owner common.Address
Spender common.Address
Value *big.Int
Raw types.Log // Blockchain specific contextual infos
}
// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925.
//
// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value)
func (_IERC20 *IERC20Filterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*IERC20ApprovalIterator, error) {
var ownerRule []interface{}
for _, ownerItem := range owner {
ownerRule = append(ownerRule, ownerItem)
}
var spenderRule []interface{}
for _, spenderItem := range spender {
spenderRule = append(spenderRule, spenderItem)
}
logs, sub, err := _IERC20.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule)
if err != nil {
return nil, err
}
return &IERC20ApprovalIterator{contract: _IERC20.contract, event: "Approval", logs: logs, sub: sub}, nil
}
// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925.
//
// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value)
func (_IERC20 *IERC20Filterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *IERC20Approval, owner []common.Address, spender []common.Address) (event.Subscription, error) {
var ownerRule []interface{}
for _, ownerItem := range owner {
ownerRule = append(ownerRule, ownerItem)
}
var spenderRule []interface{}
for _, spenderItem := range spender {
spenderRule = append(spenderRule, spenderItem)
}
logs, sub, err := _IERC20.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule)
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(IERC20Approval)
if err := _IERC20.contract.UnpackLog(event, "Approval", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925.
//
// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value)
func (_IERC20 *IERC20Filterer) ParseApproval(log types.Log) (*IERC20Approval, error) {
event := new(IERC20Approval)
if err := _IERC20.contract.UnpackLog(event, "Approval", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}
// IERC20TransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the IERC20 contract.
type IERC20TransferIterator struct {
Event *IERC20Transfer // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *IERC20TransferIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(IERC20Transfer)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(IERC20Transfer)
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *IERC20TransferIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *IERC20TransferIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// IERC20Transfer represents a Transfer event raised by the IERC20 contract.
type IERC20Transfer struct {
From common.Address
To common.Address
Value *big.Int
Raw types.Log // Blockchain specific contextual infos
}
// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef.
//
// Solidity: event Transfer(address indexed from, address indexed to, uint256 value)
func (_IERC20 *IERC20Filterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*IERC20TransferIterator, error) {
var fromRule []interface{}
for _, fromItem := range from {
fromRule = append(fromRule, fromItem)
}
var toRule []interface{}
for _, toItem := range to {
toRule = append(toRule, toItem)
}
logs, sub, err := _IERC20.contract.FilterLogs(opts, "Transfer", fromRule, toRule)
if err != nil {
return nil, err
}
return &IERC20TransferIterator{contract: _IERC20.contract, event: "Transfer", logs: logs, sub: sub}, nil
}
// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef.
//
// Solidity: event Transfer(address indexed from, address indexed to, uint256 value)
func (_IERC20 *IERC20Filterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *IERC20Transfer, from []common.Address, to []common.Address) (event.Subscription, error) {
var fromRule []interface{}
for _, fromItem := range from {
fromRule = append(fromRule, fromItem)
}
var toRule []interface{}
for _, toItem := range to {
toRule = append(toRule, toItem)
}
logs, sub, err := _IERC20.contract.WatchLogs(opts, "Transfer", fromRule, toRule)
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(IERC20Transfer)
if err := _IERC20.contract.UnpackLog(event, "Transfer", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef.
//
// Solidity: event Transfer(address indexed from, address indexed to, uint256 value)
func (_IERC20 *IERC20Filterer) ParseTransfer(log types.Log) (*IERC20Transfer, error) {
event := new(IERC20Transfer)
if err := _IERC20.contract.UnpackLog(event, "Transfer", log); err != nil {
return nil, err
}
event.Raw = log
return event, nil
}

View File

@@ -0,0 +1,96 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.4.24;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount)
external
returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender)
external
view
returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}

View File

@@ -0,0 +1,297 @@
// This solidity file was added to the project to generate the ABI to consume
// the smart contract deployed at 0xDB5ac1a559b02E12F29fC0eC0e37Be8E046DEF49
pragma solidity ^0.4.24;
contract Controlled {
address public controller;
/// @notice Changes the controller of the contract
/// @param _newController The new controller of the contract
function changeController(address _newController) public;
}
contract ApproveAndCallFallBack {
function receiveApproval(
address from,
uint256 _amount,
address _token,
bytes _data
) public;
}
contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
address public token;
address public ensRegistry;
address public resolver;
address public parentRegistry;
uint256 public constant releaseDelay = 365 days;
mapping(bytes32 => Account) public accounts;
mapping(bytes32 => SlashReserve) reservedSlashers;
//Slashing conditions
uint256 public usernameMinLength;
bytes32 public reservedUsernamesMerkleRoot;
event RegistryState(RegistrarState state);
event RegistryPrice(uint256 price);
event RegistryMoved(address newRegistry);
event UsernameOwner(bytes32 indexed nameHash, address owner);
enum RegistrarState {
Inactive,
Active,
Moved
}
bytes32 public ensNode;
uint256 public price;
RegistrarState public state;
uint256 public reserveAmount;
struct Account {
uint256 balance;
uint256 creationTime;
address owner;
}
struct SlashReserve {
address reserver;
uint256 blockNumber;
}
/**
* @notice Registers `_label` username to `ensNode` setting msg.sender as owner.
* Terms of name registration:
* - SNT is deposited, not spent; the amount is locked up for 1 year.
* - After 1 year, the user can release the name and receive their deposit back (at any time).
* - User deposits are completely protected. The contract controller cannot access them.
* - User's address(es) will be publicly associated with the ENS name.
* - User must authorise the contract to transfer `price` `token.name()` on their behalf.
* - Usernames registered with less then `usernameMinLength` characters can be slashed.
* - Usernames contained in the merkle tree of root `reservedUsernamesMerkleRoot` can be slashed.
* - Usernames starting with `0x` and bigger then 12 characters can be slashed.
* - If terms of the contract change—e.g. Status makes contract upgrades—the user has the right to release the username and get their deposit back.
* @param _label Choosen unowned username hash.
* @param _account Optional address to set at public resolver.
* @param _pubkeyA Optional pubkey part A to set at public resolver.
* @param _pubkeyB Optional pubkey part B to set at public resolver.
*/
function register(
bytes32 _label,
address _account,
bytes32 _pubkeyA,
bytes32 _pubkeyB
) external returns (bytes32 namehash);
/**
* @notice Release username and retrieve locked fee, needs to be called
* after `releasePeriod` from creation time by ENS registry owner of domain
* or anytime by account owner when domain migrated to a new registry.
* @param _label Username hash.
*/
function release(bytes32 _label) external;
/**
* @notice update account owner, should be called by new ens node owner
* to update this contract registry, otherwise former owner can release
* if domain is moved to a new registry.
* @param _label Username hash.
**/
function updateAccountOwner(bytes32 _label) external;
/**
* @notice secretly reserve the slashing reward to `msg.sender`
* @param _secret keccak256(abi.encodePacked(namehash, creationTime, reserveSecret))
*/
function reserveSlash(bytes32 _secret) external;
/**
* @notice Slash username smaller then `usernameMinLength`.
* @param _username Raw value of offending username.
*/
function slashSmallUsername(string _username, uint256 _reserveSecret)
external;
/**
* @notice Slash username starting with "0x" and with length greater than 12.
* @param _username Raw value of offending username.
*/
function slashAddressLikeUsername(string _username, uint256 _reserveSecret)
external;
/**
* @notice Slash username that is exactly a reserved name.
* @param _username Raw value of offending username.
* @param _proof Merkle proof that name is listed on merkle tree.
*/
function slashReservedUsername(
string _username,
bytes32[] _proof,
uint256 _reserveSecret
) external;
/**
* @notice Slash username that contains a non alphanumeric character.
* @param _username Raw value of offending username.
* @param _offendingPos Position of non alphanumeric character.
*/
function slashInvalidUsername(
string _username,
uint256 _offendingPos,
uint256 _reserveSecret
) external;
/**
* @notice Clear resolver and ownership of unowned subdomians.
* @param _labels Sequence to erase.
*/
function eraseNode(bytes32[] _labels) external;
/**
* @notice Migrate account to new registry, opt-in to new contract.
* @param _label Username hash.
**/
function moveAccount(bytes32 _label, UsernameRegistrar _newRegistry)
external;
/**
* @notice Activate registration.
* @param _price The price of registration.
*/
function activate(uint256 _price) external;
/**
* @notice Updates Public Resolver for resolving users.
* @param _resolver New PublicResolver.
*/
function setResolver(address _resolver) external;
/**
* @notice Updates registration price.
* @param _price New registration price.
*/
function updateRegistryPrice(uint256 _price) external;
/**
* @notice Transfer ownership of ensNode to `_newRegistry`.
* Usernames registered are not affected, but they would be able to instantly release.
* @param _newRegistry New UsernameRegistrar for hodling `ensNode` node.
*/
function moveRegistry(UsernameRegistrar _newRegistry) external;
/**
* @notice Opt-out migration of username from `parentRegistry()`.
* Clear ENS resolver and subnode owner.
* @param _label Username hash.
*/
function dropUsername(bytes32 _label) external;
/**
* @notice Withdraw not reserved tokens
* @param _token Address of ERC20 withdrawing excess, or address(0) if want ETH.
* @param _beneficiary Address to send the funds.
**/
function withdrawExcessBalance(address _token, address _beneficiary)
external;
/**
* @notice Withdraw ens nodes not belonging to this contract.
* @param _domainHash Ens node namehash.
* @param _beneficiary New owner of ens node.
**/
function withdrawWrongNode(bytes32 _domainHash, address _beneficiary)
external;
/**
* @notice Gets registration price.
* @return Registration price.
**/
function getPrice() external view returns (uint256 registryPrice);
/**
* @notice reads amount tokens locked in username
* @param _label Username hash.
* @return Locked username balance.
**/
function getAccountBalance(bytes32 _label)
external
view
returns (uint256 accountBalance);
/**
* @notice reads username account owner at this contract,
* which can release or migrate in case of upgrade.
* @param _label Username hash.
* @return Username account owner.
**/
function getAccountOwner(bytes32 _label)
external
view
returns (address owner);
/**
* @notice reads when the account was registered
* @param _label Username hash.
* @return Registration time.
**/
function getCreationTime(bytes32 _label)
external
view
returns (uint256 creationTime);
/**
* @notice calculate time where username can be released
* @param _label Username hash.
* @return Exact time when username can be released.
**/
function getExpirationTime(bytes32 _label)
external
view
returns (uint256 releaseTime);
/**
* @notice calculate reward part an account could payout on slash
* @param _label Username hash.
* @return Part of reward
**/
function getSlashRewardPart(bytes32 _label)
external
view
returns (uint256 partReward);
/**
* @notice Support for "approveAndCall". Callable only by `token()`.
* @param _from Who approved.
* @param _amount Amount being approved, need to be equal `getPrice()`.
* @param _token Token being approved, need to be equal `token()`.
* @param _data Abi encoded data with selector of `register(bytes32,address,bytes32,bytes32)`.
*/
function receiveApproval(
address _from,
uint256 _amount,
address _token,
bytes _data
) public;
/**
* @notice Continues migration of username to new registry.
* @param _label Username hash.
* @param _tokenBalance Amount being transfered from `parentRegistry()`.
* @param _creationTime Time user registrated in `parentRegistry()` is preserved.
* @param _accountOwner Account owner which migrated the account.
**/
function migrateUsername(
bytes32 _label,
uint256 _tokenBalance,
uint256 _creationTime,
address _accountOwner
) external;
/**
* @dev callable only by parent registry to continue migration
* of registry and activate registration.
* @param _price The price of registration.
**/
function migrateRegistry(uint256 _price) external;
}

View File

@@ -0,0 +1,3 @@
package registrar
//go:generate abigen -sol Registrar.sol -pkg registrar -out registrar.go

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,23 @@
package resolver
import (
"errors"
"github.com/ethereum/go-ethereum/common"
)
var errorNotAvailableOnChainID = errors.New("not available for chainID")
var contractAddressByChainID = map[uint64]common.Address{
1: common.HexToAddress("0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"), // mainnet
5: common.HexToAddress("0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"), // goerli
11155111: common.HexToAddress("0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"), // sepolia testnet
}
func ContractAddress(chainID uint64) (common.Address, error) {
addr, exists := contractAddressByChainID[chainID]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
return addr, nil
}

View File

@@ -0,0 +1,3 @@
package resolver
//go:generate abigen -sol resolver.sol -pkg resolver -out resolver.go

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,555 @@
// This solidity file was added to the project to generate the ABI to consume
// the smart contract deployed at 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
pragma solidity >=0.4.24;
interface ENS {
// Logged when the owner of a node assigns a new owner to a subnode.
event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner);
// Logged when the owner of a node transfers ownership to a new account.
event Transfer(bytes32 indexed node, address owner);
// Logged when the resolver for a node changes.
event NewResolver(bytes32 indexed node, address resolver);
// Logged when the TTL of a node changes
event NewTTL(bytes32 indexed node, uint64 ttl);
// Logged when an operator is added or removed.
event ApprovalForAll(
address indexed owner,
address indexed operator,
bool approved
);
function setRecord(
bytes32 node,
address owner,
address resolver,
uint64 ttl
) external;
function setSubnodeRecord(
bytes32 node,
bytes32 label,
address owner,
address resolver,
uint64 ttl
) external;
function setSubnodeOwner(
bytes32 node,
bytes32 label,
address owner
) external returns (bytes32);
function setResolver(bytes32 node, address resolver) external;
function setOwner(bytes32 node, address owner) external;
function setTTL(bytes32 node, uint64 ttl) external;
function setApprovalForAll(address operator, bool approved) external;
function owner(bytes32 node) external view returns (address);
function resolver(bytes32 node) external view returns (address);
function ttl(bytes32 node) external view returns (uint64);
function recordExists(bytes32 node) external view returns (bool);
function isApprovedForAll(address owner, address operator)
external
view
returns (bool);
}
/**
* The ENS registry contract.
*/
contract ENSRegistry is ENS {
struct Record {
address owner;
address resolver;
uint64 ttl;
}
/**
* @dev Sets the record for a node.
* @param node The node to update.
* @param owner The address of the new owner.
* @param resolver The address of the resolver.
* @param ttl The TTL in seconds.
*/
function setRecord(
bytes32 node,
address owner,
address resolver,
uint64 ttl
) external;
/**
* @dev Sets the record for a subnode.
* @param node The parent node.
* @param label The hash of the label specifying the subnode.
* @param owner The address of the new owner.
* @param resolver The address of the resolver.
* @param ttl The TTL in seconds.
*/
function setSubnodeRecord(
bytes32 node,
bytes32 label,
address owner,
address resolver,
uint64 ttl
) external;
/**
* @dev Transfers ownership of a node to a new address. May only be called by the current owner of the node.
* @param node The node to transfer ownership of.
* @param owner The address of the new owner.
*/
function setOwner(bytes32 node, address owner) public;
/**
* @dev Transfers ownership of a subnode keccak256(node, label) to a new address. May only be called by the owner of the parent node.
* @param node The parent node.
* @param label The hash of the label specifying the subnode.
* @param owner The address of the new owner.
*/
function setSubnodeOwner(
bytes32 node,
bytes32 label,
address owner
) public returns (bytes32);
/**
* @dev Sets the resolver address for the specified node.
* @param node The node to update.
* @param resolver The address of the resolver.
*/
function setResolver(bytes32 node, address resolver) public;
/**
* @dev Sets the TTL for the specified node.
* @param node The node to update.
* @param ttl The TTL in seconds.
*/
function setTTL(bytes32 node, uint64 ttl) public;
/**
* @dev Enable or disable approval for a third party ("operator") to manage
* all of `msg.sender`'s ENS records. Emits the ApprovalForAll event.
* @param operator Address to add to the set of authorized operators.
* @param approved True if the operator is approved, false to revoke approval.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns the address that owns the specified node.
* @param node The specified node.
* @return address of the owner.
*/
function owner(bytes32 node) public view returns (address);
/**
* @dev Returns the address of the resolver for the specified node.
* @param node The specified node.
* @return address of the resolver.
*/
function resolver(bytes32 node) public view returns (address);
/**
* @dev Returns the TTL of a node, and any records associated with it.
* @param node The specified node.
* @return ttl of the node.
*/
function ttl(bytes32 node) public view returns (uint64);
/**
* @dev Returns whether a record has been imported to the registry.
* @param node The specified node.
* @return Bool if record exists
*/
function recordExists(bytes32 node) public view returns (bool);
/**
* @dev Query if an address is an authorized operator for another address.
* @param owner The address that owns the records.
* @param operator The address that acts on behalf of the owner.
* @return True if `operator` is an approved operator for `owner`, false otherwise.
*/
function isApprovedForAll(address owner, address operator)
external
view
returns (bool);
}
/**
* The ENS registry contract.
*/
contract ENSRegistryWithFallback is ENSRegistry {
/**
* @dev Returns the address of the resolver for the specified node.
* @param node The specified node.
* @return address of the resolver.
*/
function resolver(bytes32 node) public view returns (address);
/**
* @dev Returns the address that owns the specified node.
* @param node The specified node.
* @return address of the owner.
*/
function owner(bytes32 node) public view returns (address);
/**
* @dev Returns the TTL of a node, and any records associated with it.
* @param node The specified node.
* @return ttl of the node.
*/
function ttl(bytes32 node) public view returns (uint64);
}
contract ResolverBase {
function supportsInterface(bytes4 interfaceID) public pure returns (bool);
}
contract ABIResolver is ResolverBase {
event ABIChanged(bytes32 indexed node, uint256 indexed contentType);
/**
* Sets the ABI associated with an ENS node.
* Nodes may have one ABI of each content type. To remove an ABI, set it to
* the empty string.
* @param node The node to update.
* @param contentType The content type of the ABI
* @param data The ABI data.
*/
function setABI(
bytes32 node,
uint256 contentType,
bytes calldata data
) external;
/**
* Returns the ABI associated with an ENS node.
* Defined in EIP205.
* @param node The ENS node to query
* @param contentTypes A bitwise OR of the ABI formats accepted by the caller.
* @return contentType The content type of the return value
* @return data The ABI data
*/
function ABI(bytes32 node, uint256 contentTypes)
external
view
returns (uint256, bytes memory);
function supportsInterface(bytes4 interfaceID) public pure returns (bool);
}
contract AddrResolver is ResolverBase {
event AddrChanged(bytes32 indexed node, address a);
event AddressChanged(
bytes32 indexed node,
uint256 coinType,
bytes newAddress
);
/**
* Sets the address associated with an ENS node.
* May only be called by the owner of that node in the ENS registry.
* @param node The node to update.
* @param a The address to set.
*/
function setAddr(bytes32 node, address a) external;
/**
* Returns the address associated with an ENS node.
* @param node The ENS node to query.
* @return The associated address.
*/
function addr(bytes32 node) public view returns (address payable);
function setAddr(
bytes32 node,
uint256 coinType,
bytes memory a
) public;
function addr(bytes32 node, uint256 coinType)
public
view
returns (bytes memory);
function supportsInterface(bytes4 interfaceID) public pure returns (bool);
}
contract ContentHashResolver is ResolverBase {
event ContenthashChanged(bytes32 indexed node, bytes hash);
/**
* Sets the contenthash associated with an ENS node.
* May only be called by the owner of that node in the ENS registry.
* @param node The node to update.
* @param hash The contenthash to set
*/
function setContenthash(bytes32 node, bytes calldata hash) external;
/**
* Returns the contenthash associated with an ENS node.
* @param node The ENS node to query.
* @return The associated contenthash.
*/
function contenthash(bytes32 node) external view returns (bytes memory);
function supportsInterface(bytes4 interfaceID) public pure returns (bool);
}
contract DNSResolver is ResolverBase {
// DNSRecordChanged is emitted whenever a given node/name/resource's RRSET is updated.
event DNSRecordChanged(
bytes32 indexed node,
bytes name,
uint16 resource,
bytes record
);
// DNSRecordDeleted is emitted whenever a given node/name/resource's RRSET is deleted.
event DNSRecordDeleted(bytes32 indexed node, bytes name, uint16 resource);
// DNSZoneCleared is emitted whenever a given node's zone information is cleared.
event DNSZoneCleared(bytes32 indexed node);
/**
* Set one or more DNS records. Records are supplied in wire-format.
* Records with the same node/name/resource must be supplied one after the
* other to ensure the data is updated correctly. For example, if the data
* was supplied:
* a.example.com IN A 1.2.3.4
* a.example.com IN A 5.6.7.8
* www.example.com IN CNAME a.example.com.
* then this would store the two A records for a.example.com correctly as a
* single RRSET, however if the data was supplied:
* a.example.com IN A 1.2.3.4
* www.example.com IN CNAME a.example.com.
* a.example.com IN A 5.6.7.8
* then this would store the first A record, the CNAME, then the second A
* record which would overwrite the first.
*
* @param node the namehash of the node for which to set the records
* @param data the DNS wire format records to set
*/
function setDNSRecords(bytes32 node, bytes calldata data) external;
/**
* Obtain a DNS record.
* @param node the namehash of the node for which to fetch the record
* @param name the keccak-256 hash of the fully-qualified name for which to fetch the record
* @param resource the ID of the resource as per https://en.wikipedia.org/wiki/List_of_DNS_record_types
* @return the DNS record in wire format if present, otherwise empty
*/
function dnsRecord(
bytes32 node,
bytes32 name,
uint16 resource
) public view returns (bytes memory);
/**
* Check if a given node has records.
* @param node the namehash of the node for which to check the records
* @param name the namehash of the node for which to check the records
*/
function hasDNSRecords(bytes32 node, bytes32 name)
public
view
returns (bool);
/**
* Clear all information for a DNS zone.
* @param node the namehash of the node for which to clear the zone
*/
function clearDNSZone(bytes32 node) public;
function supportsInterface(bytes4 interfaceID) public pure returns (bool);
}
contract InterfaceResolver is ResolverBase, AddrResolver {
event InterfaceChanged(
bytes32 indexed node,
bytes4 indexed interfaceID,
address implementer
);
/**
* Sets an interface associated with a name.
* Setting the address to 0 restores the default behaviour of querying the contract at `addr()` for interface support.
* @param node The node to update.
* @param interfaceID The EIP 168 interface ID.
* @param implementer The address of a contract that implements this interface for this node.
*/
function setInterface(
bytes32 node,
bytes4 interfaceID,
address implementer
) external;
/**
* Returns the address of a contract that implements the specified interface for this name.
* If an implementer has not been set for this interfaceID and name, the resolver will query
* the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that
* contract implements EIP168 and returns `true` for the specified interfaceID, its address
* will be returned.
* @param node The ENS node to query.
* @param interfaceID The EIP 168 interface ID to check for.
* @return The address that implements this interface, or 0 if the interface is unsupported.
*/
function interfaceImplementer(bytes32 node, bytes4 interfaceID)
external
view
returns (address);
function supportsInterface(bytes4 interfaceID) public pure returns (bool);
}
contract NameResolver is ResolverBase {
event NameChanged(bytes32 indexed node, string name);
/**
* Sets the name associated with an ENS node, for reverse records.
* May only be called by the owner of that node in the ENS registry.
* @param node The node to update.
* @param name The name to set.
*/
function setName(bytes32 node, string calldata name) external;
/**
* Returns the name associated with an ENS node, for reverse records.
* Defined in EIP181.
* @param node The ENS node to query.
* @return The associated name.
*/
function name(bytes32 node) external view returns (string memory);
function supportsInterface(bytes4 interfaceID) public pure returns (bool);
}
contract PubkeyResolver is ResolverBase {
event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);
struct PublicKey {
bytes32 x;
bytes32 y;
}
/**
* Sets the SECP256k1 public key associated with an ENS node.
* @param node The ENS node to query
* @param x the X coordinate of the curve point for the public key.
* @param y the Y coordinate of the curve point for the public key.
*/
function setPubkey(
bytes32 node,
bytes32 x,
bytes32 y
) external;
/**
* Returns the SECP256k1 public key associated with an ENS node.
* Defined in EIP 619.
* @param node The ENS node to query
* @return x, y the X and Y coordinates of the curve point for the public key.
*/
function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y);
function supportsInterface(bytes4 interfaceID) public pure returns (bool);
}
contract TextResolver is ResolverBase {
event TextChanged(
bytes32 indexed node,
string indexed indexedKey,
string key
);
/**
* Sets the text data associated with an ENS node and key.
* May only be called by the owner of that node in the ENS registry.
* @param node The node to update.
* @param key The key to set.
* @param value The text data value to set.
*/
function setText(
bytes32 node,
string calldata key,
string calldata value
) external;
/**
* Returns the text data associated with an ENS node and key.
* @param node The ENS node to query.
* @param key The text data key to query.
* @return The associated text data.
*/
function text(bytes32 node, string calldata key)
external
view
returns (string memory);
function supportsInterface(bytes4 interfaceID) public pure returns (bool);
}
pragma experimental ABIEncoderV2;
/**
* A simple resolver anyone can use; only allows the owner of a node to set its
* address.
*/
contract PublicResolver is
ABIResolver,
AddrResolver,
ContentHashResolver,
DNSResolver,
InterfaceResolver,
NameResolver,
PubkeyResolver,
TextResolver
{
/**
* A mapping of authorisations. An address that is authorised for a name
* may make any changes to the name that the owner could, but may not update
* the set of authorisations.
* (node, owner, caller) => isAuthorised
*/
mapping(bytes32 => mapping(address => mapping(address => bool)))
public authorisations;
event AuthorisationChanged(
bytes32 indexed node,
address indexed owner,
address indexed target,
bool isAuthorised
);
/**
* @dev Sets or clears an authorisation.
* Authorisations are specific to the caller. Any account can set an authorisation
* for any name, but the authorisation that is checked will be that of the
* current owner of a name. Thus, transferring a name effectively clears any
* existing authorisations, and new authorisations can be set in advance of
* an ownership transfer if desired.
*
* @param node The name to change the authorisation on.
* @param target The address that is to be authorised or deauthorised.
* @param isAuthorised True if the address should be authorised, or false if it should be deauthorised.
*/
function setAuthorisation(
bytes32 node,
address target,
bool isAuthorised
) external;
function multicall(bytes[] calldata data)
external
returns (bytes[] memory results);
}

View File

@@ -0,0 +1,22 @@
package snt
import (
"errors"
"github.com/ethereum/go-ethereum/common"
)
var errorNotAvailableOnChainID = errors.New("not available for chainID")
var contractAddressByChainID = map[uint64]common.Address{
1: common.HexToAddress("0x744d70fdbe2ba4cf95131626614a1763df805b9e"), // mainnet
5: common.HexToAddress("0x3d6afaa395c31fcd391fe3d562e75fe9e8ec7e6a"), // goerli
}
func ContractAddress(chainID uint64) (common.Address, error) {
addr, exists := contractAddressByChainID[chainID]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
return addr, nil
}

View File

@@ -0,0 +1,3 @@
package snt
//go:generate abigen -sol snt.sol -pkg snt -out snt.go

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,412 @@
// This solidity file was added to the project to generate the ABI to consume
// the smart contract deployed at 0x744d70fdbe2ba4cf95131626614a1763df805b9e
pragma solidity ^0.4.11;
// Abstract contract for the full ERC 20 Token standard
// https://github.com/ethereum/EIPs/issues/20
contract ERC20Token {
/* This is a slight change to the ERC20 base standard.
function totalSupply() constant returns (uint256 supply);
is replaced with:
uint256 public totalSupply;
This automatically creates a getter function for the totalSupply.
This is moved to the base contract since public getter functions are not
currently recognised as an implementation of the matching abstract
function by the compiler.
*/
/// total amount of tokens
uint256 public totalSupply;
/// @param _owner The address from which the balance will be retrieved
/// @return The balance
function balanceOf(address _owner) constant returns (uint256 balance);
/// @notice send `_value` token to `_to` from `msg.sender`
/// @param _to The address of the recipient
/// @param _value The amount of token to be transferred
/// @return Whether the transfer was successful or not
function transfer(address _to, uint256 _value) returns (bool success);
/// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
/// @param _from The address of the sender
/// @param _to The address of the recipient
/// @param _value The amount of token to be transferred
/// @return Whether the transfer was successful or not
function transferFrom(
address _from,
address _to,
uint256 _value
) returns (bool success);
/// @notice `msg.sender` approves `_spender` to spend `_value` tokens
/// @param _spender The address of the account able to transfer the tokens
/// @param _value The amount of tokens to be approved for transfer
/// @return Whether the approval was successful or not
function approve(address _spender, uint256 _value) returns (bool success);
/// @param _owner The address of the account owning tokens
/// @param _spender The address of the account able to transfer the tokens
/// @return Amount of remaining tokens allowed to spent
function allowance(address _owner, address _spender)
constant
returns (uint256 remaining);
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(
address indexed _owner,
address indexed _spender,
uint256 _value
);
}
/*
Copyright 2016, Jordi Baylina
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/// @title MiniMeToken Contract
/// @author Jordi Baylina
/// @dev This token contract's goal is to make it easy for anyone to clone this
/// token using the token distribution at a given block, this will allow DAO's
/// and DApps to upgrade their features in a decentralized manner without
/// affecting the original token
/// @dev It is ERC20 compliant, but still needs to under go further testing.
/// @dev The token controller contract must implement these functions
contract TokenController {
/// @notice Called when `_owner` sends ether to the MiniMe Token contract
/// @param _owner The address that sent the ether to create tokens
/// @return True if the ether is accepted, false if it throws
function proxyPayment(address _owner) payable returns (bool);
/// @notice Notifies the controller about a token transfer allowing the
/// controller to react if desired
/// @param _from The origin of the transfer
/// @param _to The destination of the transfer
/// @param _amount The amount of the transfer
/// @return False if the controller does not authorize the transfer
function onTransfer(
address _from,
address _to,
uint256 _amount
) returns (bool);
/// @notice Notifies the controller about an approval allowing the
/// controller to react if desired
/// @param _owner The address that calls `approve()`
/// @param _spender The spender in the `approve()` call
/// @param _amount The amount in the `approve()` call
/// @return False if the controller does not authorize the approval
function onApprove(
address _owner,
address _spender,
uint256 _amount
) returns (bool);
}
contract Controlled {
address public controller;
function Controlled() {}
/// @notice Changes the controller of the contract
/// @param _newController The new controller of the contract
function changeController(address _newController) {}
}
contract ApproveAndCallFallBack {
function receiveApproval(
address from,
uint256 _amount,
address _token,
bytes _data
);
}
/// @dev The actual token contract, the default controller is the msg.sender
/// that deploys the contract, so usually this token will be deployed by a
/// token controller contract, which Giveth will call a "Campaign"
contract MiniMeToken is Controlled {
string public name; //The Token's name: e.g. DigixDAO Tokens
uint8 public decimals; //Number of decimals of the smallest unit
string public symbol; //An identifier: e.g. REP
string public version = "MMT_0.1"; //An arbitrary versioning scheme
/// @dev `Checkpoint` is the structure that attaches a block number to a
/// given value, the block number attached is the one that last changed the
/// value
struct Checkpoint {
// `fromBlock` is the block number that the value was generated from
uint128 fromBlock;
// `value` is the amount of tokens at a specific block number
uint128 value;
}
// `parentToken` is the Token address that was cloned to produce this token;
// it will be 0x0 for a token that was not cloned
MiniMeToken public parentToken;
// `parentSnapShotBlock` is the block number from the Parent Token that was
// used to determine the initial distribution of the Clone Token
uint256 public parentSnapShotBlock;
// `creationBlock` is the block number that the Clone Token was created
uint256 public creationBlock;
// `balances` is the map that tracks the balance of each address, in this
// contract when the balance changes the block number that the change
// occurred is also included in the map
mapping(address => Checkpoint[]) balances;
// `allowed` tracks any extra transfer rights as in all ERC20 tokens
mapping(address => mapping(address => uint256)) allowed;
// Tracks the history of the `totalSupply` of the token
Checkpoint[] totalSupplyHistory;
// Flag that determines if the token is transferable or not.
bool public transfersEnabled;
// The factory used to create new clone tokens
MiniMeTokenFactory public tokenFactory;
////////////////
// Constructor
////////////////
/// @notice Constructor to create a MiniMeToken
/// @param _tokenFactory The address of the MiniMeTokenFactory contract that
/// will create the Clone token contracts, the token factory needs to be
/// deployed first
/// @param _parentToken Address of the parent token, set to 0x0 if it is a
/// new token
/// @param _parentSnapShotBlock Block of the parent token that will
/// determine the initial distribution of the clone token, set to 0 if it
/// is a new token
/// @param _tokenName Name of the new token
/// @param _decimalUnits Number of decimals of the new token
/// @param _tokenSymbol Token Symbol for the new token
/// @param _transfersEnabled If true, tokens will be able to be transferred
function MiniMeToken(
address _tokenFactory,
address _parentToken,
uint256 _parentSnapShotBlock,
string _tokenName,
uint8 _decimalUnits,
string _tokenSymbol,
bool _transfersEnabled
) {}
///////////////////
// ERC20 Methods
///////////////////
/// @notice Send `_amount` tokens to `_to` from `msg.sender`
/// @param _to The address of the recipient
/// @param _amount The amount of tokens to be transferred
/// @return Whether the transfer was successful or not
function transfer(address _to, uint256 _amount) returns (bool success) {}
/// @notice Send `_amount` tokens to `_to` from `_from` on the condition it
/// is approved by `_from`
/// @param _from The address holding the tokens being transferred
/// @param _to The address of the recipient
/// @param _amount The amount of tokens to be transferred
/// @return True if the transfer was successful
function transferFrom(
address _from,
address _to,
uint256 _amount
) returns (bool success) {}
/// @param _owner The address that's balance is being requested
/// @return The balance of `_owner` at the current block
function balanceOf(address _owner) constant returns (uint256 balance) {}
/// @notice `msg.sender` approves `_spender` to spend `_amount` tokens on
/// its behalf. This is a modified version of the ERC20 approve function
/// to be a little bit safer
/// @param _spender The address of the account able to transfer the tokens
/// @param _amount The amount of tokens to be approved for transfer
/// @return True if the approval was successful
function approve(address _spender, uint256 _amount)
returns (bool success)
{}
/// @dev This function makes it easy to read the `allowed[]` map
/// @param _owner The address of the account that owns the token
/// @param _spender The address of the account able to transfer the tokens
/// @return Amount of remaining tokens of _owner that _spender is allowed
/// to spend
function allowance(address _owner, address _spender)
constant
returns (uint256 remaining)
{}
/// @notice `msg.sender` approves `_spender` to send `_amount` tokens on
/// its behalf, and then a function is triggered in the contract that is
/// being approved, `_spender`. This allows users to use their tokens to
/// interact with contracts in one function call instead of two
/// @param _spender The address of the contract able to transfer the tokens
/// @param _amount The amount of tokens to be approved for transfer
/// @return True if the function call was successful
function approveAndCall(
address _spender,
uint256 _amount,
bytes _extraData
) returns (bool success) {}
/// @dev This function makes it easy to get the total number of tokens
/// @return The total number of tokens
function totalSupply() constant returns (uint256) {}
////////////////
// Query balance and totalSupply in History
////////////////
/// @dev Queries the balance of `_owner` at a specific `_blockNumber`
/// @param _owner The address from which the balance will be retrieved
/// @param _blockNumber The block number when the balance is queried
/// @return The balance at `_blockNumber`
function balanceOfAt(address _owner, uint256 _blockNumber)
constant
returns (uint256)
{}
/// @notice Total amount of tokens at a specific `_blockNumber`.
/// @param _blockNumber The block number when the totalSupply is queried
/// @return The total amount of tokens at `_blockNumber`
function totalSupplyAt(uint256 _blockNumber) constant returns (uint256) {}
////////////////
// Clone Token Method
////////////////
/// @notice Creates a new clone token with the initial distribution being
/// this token at `_snapshotBlock`
/// @param _cloneTokenName Name of the clone token
/// @param _cloneDecimalUnits Number of decimals of the smallest unit
/// @param _cloneTokenSymbol Symbol of the clone token
/// @param _snapshotBlock Block when the distribution of the parent token is
/// copied to set the initial distribution of the new clone token;
/// if the block is zero than the actual block, the current block is used
/// @param _transfersEnabled True if transfers are allowed in the clone
/// @return The address of the new MiniMeToken Contract
function createCloneToken(
string _cloneTokenName,
uint8 _cloneDecimalUnits,
string _cloneTokenSymbol,
uint256 _snapshotBlock,
bool _transfersEnabled
) returns (address) {}
////////////////
// Generate and destroy tokens
////////////////
/// @notice Generates `_amount` tokens that are assigned to `_owner`
/// @param _owner The address that will be assigned the new tokens
/// @param _amount The quantity of tokens generated
/// @return True if the tokens are generated correctly
function generateTokens(address _owner, uint256 _amount) returns (bool) {}
/// @notice Burns `_amount` tokens from `_owner`
/// @param _owner The address that will lose the tokens
/// @param _amount The quantity of tokens to burn
/// @return True if the tokens are burned correctly
function destroyTokens(address _owner, uint256 _amount) returns (bool) {}
////////////////
// Enable tokens transfers
////////////////
/// @notice Enables token holders to transfer their tokens freely if true
/// @param _transfersEnabled True if transfers are allowed in the clone
function enableTransfers(bool _transfersEnabled) {}
/// @dev Helper function to return a min betwen the two uints
function min(uint256 a, uint256 b) internal returns (uint256) {
return a < b ? a : b;
}
/// @notice The fallback function: If the contract's controller has not been
/// set to 0, then the `proxyPayment` method is called which relays the
/// ether and creates tokens as described in the token controller contract
function() payable {}
//////////
// Safety Methods
//////////
/// @notice This method can be used by the controller to extract mistakenly
/// sent tokens to this contract.
/// @param _token The address of the token contract that you want to recover
/// set to 0 in case you want to extract ether.
function claimTokens(address _token) {}
////////////////
// Events
////////////////
event ClaimedTokens(
address indexed _token,
address indexed _controller,
uint256 _amount
);
event Transfer(address indexed _from, address indexed _to, uint256 _amount);
event NewCloneToken(address indexed _cloneToken, uint256 _snapshotBlock);
event Approval(
address indexed _owner,
address indexed _spender,
uint256 _amount
);
}
////////////////
// MiniMeTokenFactory
////////////////
/// @dev This contract is used to generate clone contracts from a contract.
/// In solidity this is the way to create a contract from a contract of the
/// same class
contract MiniMeTokenFactory {
/// @notice Update the DApp by creating a new token with new functionalities
/// the msg.sender becomes the controller of this clone token
/// @param _parentToken Address of the token being cloned
/// @param _snapshotBlock Block of the parent token that will
/// determine the initial distribution of the clone token
/// @param _tokenName Name of the new token
/// @param _decimalUnits Number of decimals of the new token
/// @param _tokenSymbol Token Symbol for the new token
/// @param _transfersEnabled If true, tokens will be able to be transferred
/// @return The address of the new token contract
function createCloneToken(
address _parentToken,
uint256 _snapshotBlock,
string _tokenName,
uint8 _decimalUnits,
string _tokenSymbol,
bool _transfersEnabled
) returns (MiniMeToken);
}
/*
Copyright 2017, Jarrad Hope (Status Research & Development GmbH)
*/
contract SNT is MiniMeToken {
}

View File

@@ -0,0 +1,51 @@
package stickers
import (
"errors"
"github.com/ethereum/go-ethereum/common"
)
var errorNotAvailableOnChainID = errors.New("not available for chainID")
var stickerTypeByChainID = map[uint64]common.Address{
1: common.HexToAddress("0x0577215622f43a39f4bc9640806dfea9b10d2a36"), // mainnet
5: common.HexToAddress("0x07f7CB0C0a4ab3e0999AfE8b3997Da34880f05d0"), // goerli testnet
11155111: common.HexToAddress("0x5acbae26c23427aeee0a7f26949f093577a61aab"), // sepolia testnet
}
var stickerMarketByChainID = map[uint64]common.Address{
1: common.HexToAddress("0x12824271339304d3a9f7e096e62a2a7e73b4a7e7"), // mainnet
5: common.HexToAddress("0xf1E149A7DF70D5Ff1E265daAa738d785D3274717"), // goerli testnet
11155111: common.HexToAddress("0xf852198d0385c4b871e0b91804ecd47c6ba97351"), // sepolia testnet
}
var stickerPackByChainID = map[uint64]common.Address{
1: common.HexToAddress("0x110101156e8F0743948B2A61aFcf3994A8Fb172e"), // mainnet
5: common.HexToAddress("0x8D3fD2EA24bD53a8Bd2b1026727db8bbe9A8C8Af"), // goerli testnet
11155111: common.HexToAddress("0x8cc272396be7583c65bee82cd7b743c69a87287d"), // sepolia testnet
}
func StickerTypeContractAddress(chainID uint64) (common.Address, error) {
addr, exists := stickerTypeByChainID[chainID]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
return addr, nil
}
func StickerMarketContractAddress(chainID uint64) (common.Address, error) {
addr, exists := stickerMarketByChainID[chainID]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
return addr, nil
}
func StickerPackContractAddress(chainID uint64) (common.Address, error) {
addr, exists := stickerPackByChainID[chainID]
if !exists {
return *new(common.Address), errorNotAvailableOnChainID
}
return addr, nil
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,771 @@
// This solidity file was added to the project to generate the ABI to consume
// these smart contracts:
// 0x0577215622f43a39f4bc9640806dfea9b10d2a36: StickerType
// 0x12824271339304d3a9f7e096e62a2a7e73b4a7e7: StickerMarket
// 0x110101156e8F0743948B2A61aFcf3994A8Fb172e: StickerPack
pragma solidity ^0.5.0;
contract Controlled {
event NewController(address controller);
address payable public controller;
/// @notice Changes the controller of the contract
/// @param _newController The new controller of the contract
function changeController(address payable _newController) public;
}
/**
* @dev Interface of the ERC165 standard, as defined in the
* [EIP](https://eips.ethereum.org/EIPS/eip-165).
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others (`ERC165Checker`).
*
* For an implementation, see `ERC165`.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
contract IERC721Receiver {
/**
* @notice Handle the receipt of an NFT
* @dev The ERC721 smart contract calls this function on the recipient
* after a `safeTransfer`. This function MUST return the function selector,
* otherwise the caller will revert the transaction. The selector to be
* returned can be obtained as `this.onERC721Received.selector`. This
* function MAY throw to revert and reject the transfer.
* Note: the ERC721 contract address is always the message sender.
* @param operator The address which called `safeTransferFrom` function
* @param from The address which previously owned the token
* @param tokenId The NFT identifier which is being transferred
* @param data Additional data with no specified format
* @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes memory data
) public returns (bytes4);
}
/**
* @dev Implementation of the `IERC165` interface.
*
* Contracts may inherit from this and call `_registerInterface` to declare
* their support of an interface.
*/
contract ERC165 is IERC165 {
/**
* @dev See `IERC165.supportsInterface`.
*
* Time complexity O(1), guaranteed to always use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
/**
* @dev Required interface of an ERC721 compliant contract.
*/
contract IERC721 is IERC165 {
event Transfer(
address indexed from,
address indexed to,
uint256 indexed tokenId
);
event Approval(
address indexed owner,
address indexed approved,
uint256 indexed tokenId
);
event ApprovalForAll(
address indexed owner,
address indexed operator,
bool approved
);
/**
* @dev Returns the number of NFTs in `owner`'s account.
*/
function balanceOf(address owner) public view returns (uint256 balance);
/**
* @dev Returns the owner of the NFT specified by `tokenId`.
*/
function ownerOf(uint256 tokenId) public view returns (address owner);
/**
* @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
* another (`to`).
*
*
*
* Requirements:
* - `from`, `to` cannot be zero.
* - `tokenId` must be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move this
* NFT by either `approve` or `setApproveForAll`.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public;
/**
* @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
* another (`to`).
*
* Requirements:
* - If the caller is not `from`, it must be approved to move this NFT by
* either `approve` or `setApproveForAll`.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public;
function approve(address to, uint256 tokenId) public;
function getApproved(uint256 tokenId)
public
view
returns (address operator);
function setApprovalForAll(address operator, bool _approved) public;
function isApprovedForAll(address owner, address operator)
public
view
returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory data
) public;
}
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
contract IERC721Enumerable is IERC721 {
function totalSupply() public view returns (uint256);
function tokenOfOwnerByIndex(address owner, uint256 index)
public
view
returns (uint256 tokenId);
function tokenByIndex(uint256 index) public view returns (uint256);
}
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
contract IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
contract TokenClaimer {
event ClaimedTokens(
address indexed _token,
address indexed _controller,
uint256 _amount
);
function claimTokens(address _token) external;
}
/**
* @title ERC721 Non-Fungible Token Standard basic implementation
* @dev see https://eips.ethereum.org/EIPS/eip-721
*/
contract ERC721 is ERC165, IERC721 {
/**
* @dev Gets the balance of the specified address.
* @param owner address to query the balance of
* @return uint256 representing the amount owned by the passed address
*/
function balanceOf(address owner) public view returns (uint256);
/**
* @dev Gets the owner of the specified token ID.
* @param tokenId uint256 ID of the token to query the owner of
* @return address currently marked as the owner of the given token ID
*/
function ownerOf(uint256 tokenId) public view returns (address);
/**
* @dev Approves another address to transfer the given token ID
* The zero address indicates there is no approved address.
* There can only be one approved address per token at a given time.
* Can only be called by the token owner or an approved operator.
* @param to address to be approved for the given token ID
* @param tokenId uint256 ID of the token to be approved
*/
function approve(address to, uint256 tokenId) public;
/**
* @dev Gets the approved address for a token ID, or zero if no address set
* Reverts if the token ID does not exist.
* @param tokenId uint256 ID of the token to query the approval of
* @return address currently approved for the given token ID
*/
function getApproved(uint256 tokenId) public view returns (address);
/**
* @dev Sets or unsets the approval of a given operator
* An operator is allowed to transfer all tokens of the sender on their behalf.
* @param to operator address to set the approval
* @param approved representing the status of the approval to be set
*/
function setApprovalForAll(address to, bool approved) public;
/**
* @dev Tells whether an operator is approved by a given owner.
* @param owner owner address which you want to query the approval of
* @param operator operator address which you want to query the approval of
* @return bool whether the given operator is approved by the given owner
*/
function isApprovedForAll(address owner, address operator)
public
view
returns (bool);
/**
* @dev Transfers the ownership of a given token ID to another address.
* Usage of this method is discouraged, use `safeTransferFrom` whenever possible.
* Requires the msg.sender to be the owner, approved, or operator.
* @param from current owner of the token
* @param to address to receive the ownership of the given token ID
* @param tokenId uint256 ID of the token to be transferred
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public;
/**
* @dev Safely transfers the ownership of a given token ID to another address
* If the target address is a contract, it must implement `onERC721Received`,
* which is called upon a safe transfer, and return the magic value
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
* the transfer is reverted.
* Requires the msg.sender to be the owner, approved, or operator
* @param from current owner of the token
* @param to address to receive the ownership of the given token ID
* @param tokenId uint256 ID of the token to be transferred
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public;
/**
* @dev Safely transfers the ownership of a given token ID to another address
* If the target address is a contract, it must implement `onERC721Received`,
* which is called upon a safe transfer, and return the magic value
* `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
* the transfer is reverted.
* Requires the msg.sender to be the owner, approved, or operator
* @param from current owner of the token
* @param to address to receive the ownership of the given token ID
* @param tokenId uint256 ID of the token to be transferred
* @param _data bytes data to send along with a safe transfer check
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public;
}
/**
* @title ERC-721 Non-Fungible Token Standard, full implementation interface
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
contract IERC721Full is IERC721, IERC721Enumerable, IERC721Metadata {
// solhint-disable-previous-line no-empty-blocks
}
/**
* @title ERC-721 Non-Fungible Token with optional enumeration extension logic
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
contract ERC721Enumerable is ERC165, ERC721, IERC721Enumerable {
/**
* @dev Gets the token ID at a given index of the tokens list of the requested owner.
* @param owner address owning the tokens list to be accessed
* @param index uint256 representing the index to be accessed of the requested tokens list
* @return uint256 token ID at the given index of the tokens list owned by the requested address
*/
function tokenOfOwnerByIndex(address owner, uint256 index)
public
view
returns (uint256);
/**
* @dev Gets the total amount of tokens stored by the contract.
* @return uint256 representing the total amount of tokens
*/
function totalSupply() public view returns (uint256);
/**
* @dev Gets the token ID at a given index of all the tokens in this contract
* Reverts if the index is greater or equal to the total number of tokens.
* @param index uint256 representing the index to be accessed of the tokens list
* @return uint256 token ID at the given index of the tokens list
*/
function tokenByIndex(uint256 index) public view returns (uint256);
}
contract ERC721Metadata is ERC165, ERC721, IERC721Metadata {
/**
* @dev Gets the token name.
* @return string representing the token name
*/
function name() external view returns (string memory);
/**
* @dev Gets the token symbol.
* @return string representing the token symbol
*/
function symbol() external view returns (string memory);
/**
* @dev Returns an URI for a given token ID.
* Throws if the token ID does not exist. May return an empty string.
* @param tokenId uint256 ID of the token to query
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}
/**
* @title Full ERC721 Token
* This implementation includes all the required and some optional functionality of the ERC721 standard
* Moreover, it includes approve all functionality using operator terminology
* @dev see https://eips.ethereum.org/EIPS/eip-721
*/
contract ERC721Full is ERC721, ERC721Enumerable, ERC721Metadata {
}
/**
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
*/
contract StickerPack is Controlled, TokenClaimer, ERC721Full {
mapping(uint256 => uint256) public tokenPackId; //packId
uint256 public tokenCount; //tokens buys
/**
* @notice controller can generate tokens at will
* @param _owner account being included new token
* @param _packId pack being minted
* @return tokenId created
*/
function generateToken(address _owner, uint256 _packId)
external
returns (uint256 tokenId);
/**
* @notice This method can be used by the controller to extract mistakenly
* sent tokens to this contract.
* @param _token The address of the token contract that you want to recover
* set to 0 in case you want to extract ether.
*/
function claimTokens(address _token) external;
}
interface ApproveAndCallFallBack {
function receiveApproval(
address from,
uint256 _amount,
address _token,
bytes calldata _data
) external;
}
/**
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* StickerMarket allows any address register "StickerPack" which can be sold to any address in form of "StickerPack", an ERC721 token.
*/
contract StickerMarket is Controlled, TokenClaimer, ApproveAndCallFallBack {
event ClaimedTokens(
address indexed _token,
address indexed _controller,
uint256 _amount
);
event MarketState(State state);
event RegisterFee(uint256 value);
event BurnRate(uint256 value);
enum State {
Invalid,
Open,
BuyOnly,
Controlled,
Closed
}
State public state = State.Open;
uint256 registerFee;
uint256 burnRate;
//include global var to set burn rate/percentage
address public snt; //payment token
StickerPack public stickerPack;
StickerType public stickerType;
/**
* @dev Mints NFT StickerPack in `msg.sender` account, and Transfers SNT using user allowance
* emit NonfungibleToken.Transfer(`address(0)`, `msg.sender`, `tokenId`)
* @notice buy a pack from market pack owner, including a StickerPack's token in msg.sender account with same metadata of `_packId`
* @param _packId id of market pack
* @param _destination owner of token being brought
* @param _price agreed price
* @return tokenId generated StickerPack token
*/
function buyToken(
uint256 _packId,
address _destination,
uint256 _price
) external returns (uint256 tokenId);
/**
* @dev emits StickerMarket.Register(`packId`, `_urlHash`, `_price`, `_contenthash`)
* @notice Registers to sell a sticker pack
* @param _price cost in wei to users minting this pack
* @param _donate value between 0-10000 representing percentage of `_price` that is donated to StickerMarket at every buy
* @param _category listing category
* @param _owner address of the beneficiary of buys
* @param _contenthash EIP1577 pack contenthash for listings
* @param _fee Fee msg.sender agrees to pay for this registration
* @return packId Market position of Sticker Pack data.
*/
function registerPack(
uint256 _price,
uint256 _donate,
bytes4[] calldata _category,
address _owner,
bytes calldata _contenthash,
uint256 _fee
) external returns (uint256 packId);
/**
* @notice MiniMeToken ApproveAndCallFallBack forwarder for registerPack and buyToken
* @param _from account calling "approve and buy"
* @param _value must be exactly whats being consumed
* @param _token must be exactly SNT contract
* @param _data abi encoded call
*/
function receiveApproval(
address _from,
uint256 _value,
address _token,
bytes calldata _data
) external;
/**
* @notice changes market state, only controller can call.
* @param _state new state
*/
function setMarketState(State _state) external;
/**
* @notice changes register fee, only controller can call.
* @param _value total SNT cost of registration
*/
function setRegisterFee(uint256 _value) external;
/**
* @notice changes burn rate percentage, only controller can call.
* @param _value new value between 0 and 10000
*/
function setBurnRate(uint256 _value) external;
/**
* @notice controller can generate packs at will
* @param _price cost in wei to users minting with _urlHash metadata
* @param _donate optional amount of `_price` that is donated to StickerMarket at every buy
* @param _category listing category
* @param _owner address of the beneficiary of buys
* @param _contenthash EIP1577 pack contenthash for listings
* @return packId Market position of Sticker Pack data.
*/
function generatePack(
uint256 _price,
uint256 _donate,
bytes4[] calldata _category,
address _owner,
bytes calldata _contenthash
) external returns (uint256 packId);
/**
* @notice removes all market data about a marketed pack, can only be called by market controller
* @param _packId pack being purged
* @param _limit limits categories being purged
*/
function purgePack(uint256 _packId, uint256 _limit) external;
/**
* @notice controller can generate tokens at will
* @param _owner account being included new token
* @param _packId pack being minted
* @return tokenId created
*/
function generateToken(address _owner, uint256 _packId)
external
returns (uint256 tokenId);
/**
* @notice Change controller of stickerType
* @param _newController new controller of stickerType.
*/
function migrate(address payable _newController) external;
/**
* @notice This method can be used by the controller to extract mistakenly
* sent tokens to this contract.
* @param _token The address of the token contract that you want to recover
* set to 0 in case you want to extract ether.
*/
function claimTokens(address _token) external;
/**
* @notice returns pack data of token
* @param _tokenId user token being queried
* @return categories, registration time and contenthash
*/
function getTokenData(uint256 _tokenId)
external
view
returns (
bytes4[] memory category,
uint256 timestamp,
bytes memory contenthash
);
// For ABI/web3.js purposes
// fired by StickerType
event Register(
uint256 indexed packId,
uint256 dataPrice,
bytes contenthash
);
// fired by StickerPack and MiniMeToken
event Transfer(
address indexed from,
address indexed to,
uint256 indexed value
);
}
/**
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
* StickerMarket allows any address register "StickerPack" which can be sold to any address in form of "StickerPack", an ERC721 token.
*/
contract StickerType is Controlled, TokenClaimer, ERC721Full {
event Register(
uint256 indexed packId,
uint256 dataPrice,
bytes contenthash,
bool mintable
);
event PriceChanged(uint256 indexed packId, uint256 dataPrice);
event MintabilityChanged(uint256 indexed packId, bool mintable);
event ContenthashChanged(uint256 indexed packid, bytes contenthash);
event Categorized(bytes4 indexed category, uint256 indexed packId);
event Uncategorized(bytes4 indexed category, uint256 indexed packId);
event Unregister(uint256 indexed packId);
struct Pack {
bytes4[] category;
bool mintable;
uint256 timestamp;
uint256 price; //in "wei"
uint256 donate; //in "percent"
bytes contenthash;
}
mapping(uint256 => Pack) public packs;
uint256 public packCount; //pack registers
/**
* @notice controller can generate packs at will
* @param _price cost in wei to users minting with _urlHash metadata
* @param _donate optional amount of `_price` that is donated to StickerMarket at every buy
* @param _category listing category
* @param _owner address of the beneficiary of buys
* @param _contenthash EIP1577 pack contenthash for listings
* @return packId Market position of Sticker Pack data.
*/
function generatePack(
uint256 _price,
uint256 _donate,
bytes4[] calldata _category,
address _owner,
bytes calldata _contenthash
) external returns (uint256 packId);
/**
* @notice removes all market data about a marketed pack, can only be called by market controller
* @param _packId position to be deleted
* @param _limit limit of categories to cleanup
*/
function purgePack(uint256 _packId, uint256 _limit) external;
/**
* @notice changes contenthash of `_packId`, can only be called by controller
* @param _packId which market position is being altered
* @param _contenthash new contenthash
*/
function setPackContenthash(uint256 _packId, bytes calldata _contenthash)
external;
/**
* @notice This method can be used by the controller to extract mistakenly
* sent tokens to this contract.
* @param _token The address of the token contract that you want to recover
* set to 0 in case you want to extract ether.
*/
function claimTokens(address _token) external;
/**
* @notice changes price of `_packId`, can only be called when market is open
* @param _packId pack id changing price settings
* @param _price cost in wei to users minting this pack
* @param _donate value between 0-10000 representing percentage of `_price` that is donated to StickerMarket at every buy
*/
function setPackPrice(
uint256 _packId,
uint256 _price,
uint256 _donate
) external;
/**
* @notice add caregory in `_packId`, can only be called when market is open
* @param _packId pack adding category
* @param _category category to list
*/
function addPackCategory(uint256 _packId, bytes4 _category) external;
/**
* @notice remove caregory in `_packId`, can only be called when market is open
* @param _packId pack removing category
* @param _category category to unlist
*/
function removePackCategory(uint256 _packId, bytes4 _category) external;
/**
* @notice Changes if pack is enabled for sell
* @param _packId position edit
* @param _mintable true to enable sell
*/
function setPackState(uint256 _packId, bool _mintable) external;
/**
* @notice read available market ids in a category (might be slow)
* @param _category listing category
* @return array of market id registered
*/
function getAvailablePacks(bytes4 _category)
external
view
returns (uint256[] memory availableIds);
/**
* @notice count total packs in a category
* @param _category listing category
* @return total number of packs in category
*/
function getCategoryLength(bytes4 _category)
external
view
returns (uint256 size);
/**
* @notice read a packId in the category list at a specific index
* @param _category listing category
* @param _index index
* @return packId on index
*/
function getCategoryPack(bytes4 _category, uint256 _index)
external
view
returns (uint256 packId);
/**
* @notice returns all data from pack in market
* @param _packId pack id being queried
* @return categories, owner, mintable, price, donate and contenthash
*/
function getPackData(uint256 _packId)
external
view
returns (
bytes4[] memory category,
address owner,
bool mintable,
uint256 timestamp,
uint256 price,
bytes memory contenthash
);
/**
* @notice returns all data from pack in market
* @param _packId pack id being queried
* @return categories, owner, mintable, price, donate and contenthash
*/
function getPackSummary(uint256 _packId)
external
view
returns (
bytes4[] memory category,
uint256 timestamp,
bytes memory contenthash
);
/**
* @notice returns payment data for migrated contract
* @param _packId pack id being queried
* @return owner, mintable, price and donate
*/
function getPaymentData(uint256 _packId)
external
view
returns (
address owner,
bool mintable,
uint256 price,
uint256 donate
);
}

View File

@@ -0,0 +1,3 @@
package stickers
//go:generate abigen -sol contracts.sol -pkg stickers -out contracts.go

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
package uniswapv2
//go:generate abigen --abi IUniswapV2Pair.abi --pkg uniswapv2 --out uniswapv2pair.go

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
[{"inputs":[{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint128","name":"amount","type":"uint128"}],"name":"burn","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint128","name":"amount0Requested","type":"uint128"},{"internalType":"uint128","name":"amount1Requested","type":"uint128"}],"name":"collect","outputs":[{"internalType":"uint128","name":"amount0","type":"uint128"},{"internalType":"uint128","name":"amount1","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"flash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"observationCardinalityNext","type":"uint16"}],"name":"increaseObservationCardinalityNext","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"mint","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"zeroForOne","type":"bool"},{"internalType":"int256","name":"amountSpecified","type":"int256"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"swap","outputs":[{"internalType":"int256","name":"amount0","type":"int256"},{"internalType":"int256","name":"amount1","type":"int256"}],"stateMutability":"nonpayable","type":"function"}]

View File

@@ -0,0 +1 @@
[{"inputs":[{"internalType":"uint32[]","name":"secondsAgos","type":"uint32[]"}],"name":"observe","outputs":[{"internalType":"int56[]","name":"tickCumulatives","type":"int56[]"},{"internalType":"uint160[]","name":"secondsPerLiquidityCumulativeX128s","type":"uint160[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"}],"name":"snapshotCumulativesInside","outputs":[{"internalType":"int56","name":"tickCumulativeInside","type":"int56"},{"internalType":"uint160","name":"secondsPerLiquidityInsideX128","type":"uint160"},{"internalType":"uint32","name":"secondsInside","type":"uint32"}],"stateMutability":"view","type":"function"}]

View File

@@ -0,0 +1 @@
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"int24","name":"tickLower","type":"int24"},{"indexed":true,"internalType":"int24","name":"tickUpper","type":"int24"},{"indexed":false,"internalType":"uint128","name":"amount","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"int24","name":"tickLower","type":"int24"},{"indexed":true,"internalType":"int24","name":"tickUpper","type":"int24"},{"indexed":false,"internalType":"uint128","name":"amount0","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"amount1","type":"uint128"}],"name":"Collect","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint128","name":"amount0","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"amount1","type":"uint128"}],"name":"CollectProtocol","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"paid0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"paid1","type":"uint256"}],"name":"Flash","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"observationCardinalityNextOld","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"observationCardinalityNextNew","type":"uint16"}],"name":"IncreaseObservationCardinalityNext","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"},{"indexed":false,"internalType":"int24","name":"tick","type":"int24"}],"name":"Initialize","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"int24","name":"tickLower","type":"int24"},{"indexed":true,"internalType":"int24","name":"tickUpper","type":"int24"},{"indexed":false,"internalType":"uint128","name":"amount","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"feeProtocol0Old","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"feeProtocol1Old","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"feeProtocol0New","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"feeProtocol1New","type":"uint8"}],"name":"SetFeeProtocol","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"int256","name":"amount0","type":"int256"},{"indexed":false,"internalType":"int256","name":"amount1","type":"int256"},{"indexed":false,"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"},{"indexed":false,"internalType":"uint128","name":"liquidity","type":"uint128"},{"indexed":false,"internalType":"int24","name":"tick","type":"int24"}],"name":"Swap","type":"event"}]

View File

@@ -0,0 +1 @@
[{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxLiquidityPerTick","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tickSpacing","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

View File

@@ -0,0 +1 @@
[{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint128","name":"amount0Requested","type":"uint128"},{"internalType":"uint128","name":"amount1Requested","type":"uint128"}],"name":"collectProtocol","outputs":[{"internalType":"uint128","name":"amount0","type":"uint128"},{"internalType":"uint128","name":"amount1","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"feeProtocol0","type":"uint8"},{"internalType":"uint8","name":"feeProtocol1","type":"uint8"}],"name":"setFeeProtocol","outputs":[],"stateMutability":"nonpayable","type":"function"}]

View File

@@ -0,0 +1 @@
[{"inputs":[],"name":"feeGrowthGlobal0X128","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeGrowthGlobal1X128","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidity","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"observations","outputs":[{"internalType":"uint32","name":"blockTimestamp","type":"uint32"},{"internalType":"int56","name":"tickCumulative","type":"int56"},{"internalType":"uint160","name":"secondsPerLiquidityCumulativeX128","type":"uint160"},{"internalType":"bool","name":"initialized","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"positions","outputs":[{"internalType":"uint128","name":"_liquidity","type":"uint128"},{"internalType":"uint256","name":"feeGrowthInside0LastX128","type":"uint256"},{"internalType":"uint256","name":"feeGrowthInside1LastX128","type":"uint256"},{"internalType":"uint128","name":"tokensOwed0","type":"uint128"},{"internalType":"uint128","name":"tokensOwed1","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFees","outputs":[{"internalType":"uint128","name":"token0","type":"uint128"},{"internalType":"uint128","name":"token1","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"slot0","outputs":[{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"},{"internalType":"int24","name":"tick","type":"int24"},{"internalType":"uint16","name":"observationIndex","type":"uint16"},{"internalType":"uint16","name":"observationCardinality","type":"uint16"},{"internalType":"uint16","name":"observationCardinalityNext","type":"uint16"},{"internalType":"uint8","name":"feeProtocol","type":"uint8"},{"internalType":"bool","name":"unlocked","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int16","name":"wordPosition","type":"int16"}],"name":"tickBitmap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int24","name":"tick","type":"int24"}],"name":"ticks","outputs":[{"internalType":"uint128","name":"liquidityGross","type":"uint128"},{"internalType":"int128","name":"liquidityNet","type":"int128"},{"internalType":"uint256","name":"feeGrowthOutside0X128","type":"uint256"},{"internalType":"uint256","name":"feeGrowthOutside1X128","type":"uint256"},{"internalType":"int56","name":"tickCumulativeOutside","type":"int56"},{"internalType":"uint160","name":"secondsPerLiquidityOutsideX128","type":"uint160"},{"internalType":"uint32","name":"secondsOutside","type":"uint32"},{"internalType":"bool","name":"initialized","type":"bool"}],"stateMutability":"view","type":"function"}]

View File

@@ -0,0 +1,3 @@
package uniswapv3
//go:generate abigen --abi IUniswapV3Pool.abi --pkg uniswapv3 --out uniswapv3pool.go

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More