return account.Signer, nil
}
+// GetAliasByID return the account alias by given ID
func (m *Manager) GetAliasByID(id string) string {
var account Account
return account.Alias
}
-// CreateP2PKH generate an address for the select account
-func (m *Manager) CreateP2PKH(ctx context.Context, accountID string, change bool, expiresAt time.Time) (*CtrlProgram, error) {
- cp, err := m.createP2PKH(ctx, accountID, change, expiresAt)
+// CreateAddress generate an address for the select account
+func (m *Manager) CreateAddress(ctx context.Context, accountID string, change bool, expiresAt time.Time) (cp *CtrlProgram, err error) {
+ account, err := m.findByID(ctx, accountID)
+ if err != nil {
+ return nil, err
+ }
+
+ if account.Quorum == 1 {
+ cp, err = m.createP2PKH(ctx, account, change, expiresAt)
+ } else {
+ cp, err = m.createP2SH(ctx, account, change, expiresAt)
+ }
if err != nil {
return nil, err
}
return cp, nil
}
-func (m *Manager) createP2PKH(ctx context.Context, accountID string, change bool, expiresAt time.Time) (*CtrlProgram, error) {
- account, err := m.findByID(ctx, accountID)
+func (m *Manager) createP2PKH(ctx context.Context, account *signers.Signer, change bool, expiresAt time.Time) (*CtrlProgram, error) {
+ idx, err := m.nextIndex(ctx)
if err != nil {
return nil, err
}
- if account.Quorum != 1 {
- return nil, ErrStandardQuorum
+ path := signers.Path(account, signers.AccountKeySpace, idx)
+ derivedXPubs := chainkd.DeriveXPubs(account.XPubs, path)
+ derivedPK := derivedXPubs[0].PublicKey()
+ pubHash := crypto.Ripemd160(derivedPK)
+
+ // TODO: pass different params due to config
+ address, err := common.NewAddressWitnessPubKeyHash(pubHash, &consensus.MainNetParams)
+ if err != nil {
+ return nil, err
}
+ control, err := vmutil.P2PKHSigProgram([]byte(pubHash))
+ if err != nil {
+ return nil, err
+ }
+
+ return &CtrlProgram{
+ AccountID: account.ID,
+ Address: address.EncodeAddress(),
+ KeyIndex: idx,
+ ControlProgram: control,
+ Change: change,
+ ExpiresAt: expiresAt,
+ }, nil
+}
+
+func (m *Manager) createP2SH(ctx context.Context, account *signers.Signer, change bool, expiresAt time.Time) (*CtrlProgram, error) {
idx, err := m.nextIndex(ctx)
if err != nil {
return nil, err
}
+
path := signers.Path(account, signers.AccountKeySpace, idx)
derivedXPubs := chainkd.DeriveXPubs(account.XPubs, path)
- derivedPK := derivedXPubs[0].PublicKey()
- pubHash := crypto.Ripemd160(derivedPK)
+ derivedPKs := chainkd.XPubKeys(derivedXPubs)
+ signScript, err := vmutil.P2SPMultiSigProgram(derivedPKs, account.Quorum)
+ if err != nil {
+ return nil, err
+ }
+ scriptHash := crypto.Sha256(signScript)
// TODO: pass different params due to config
- address, err := common.NewAddressWitnessPubKeyHash(pubHash, &consensus.MainNetParams)
+ address, err := common.NewAddressWitnessScriptHash(scriptHash, &consensus.MainNetParams)
if err != nil {
return nil, err
}
- control, err := vmutil.P2PKHSigProgram([]byte(pubHash))
+ control, err := vmutil.P2SHProgram(scriptHash)
if err != nil {
return nil, err
}