Skip to content

Commit 8552871

Browse files
authored
Implement atomic currency init and buy (#162)
* StatefulSwap RPC handles create and buy flow * Update swap antispam handler to include initialization and amount as parameters * Next currency state when initializing mint in StatefulSwap should be FundingAuthority * Initial currency metadata state in Launch RPC is now WaitingForInitialPurchase * Update currency launcher to consider accounts initialized during swap * Update currency launcher initial reserve and holder records to account for first purchase * Update swap worker to consider currency creation * Currency launcher now initializes creator accounts on success * Add first purchase handling to Geyser external deposit handler * Reduce initial authority SOL funding * Bug fixes in swap related to state management and core mint handling * Error handling fixes * Fixes for validateMinimumAuthorityFunding * Fix markSwapFinalized when destination mint is core * Fund currency authority when initial purchase from swap is at the point of submitting * Rename swap store method for consistency * Fix MetadataStateCompletingInitialization string value * Pull latest ocp-protobuf-api * Fix fee payer returned in server parameters for ReserveCreateAndBuySwapHandler * Fix finalized swap balance amount for new currencies
1 parent 98404db commit 8552871

27 files changed

Lines changed: 1088 additions & 314 deletions

File tree

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ require (
66
filippo.io/edwards25519 v1.1.0
77
github.com/aws/aws-sdk-go-v2 v0.17.0
88
github.com/code-payments/code-vm-indexer v1.2.0
9-
github.com/code-payments/ocp-protobuf-api v1.6.1-0.20260325154106-63d4d261070d
9+
github.com/code-payments/ocp-protobuf-api v1.7.1-0.20260401115005-c2265cbd04b0
1010
github.com/emirpasic/gods v1.12.0
1111
github.com/envoyproxy/protoc-gen-validate v1.2.1
1212
github.com/golang/protobuf v1.5.4

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I
7878
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
7979
github.com/code-payments/code-vm-indexer v1.2.0 h1:rSHpBMiT9BKgmKcXg/VIoi/h0t7jNxGx07Qz59m+6Q0=
8080
github.com/code-payments/code-vm-indexer v1.2.0/go.mod h1:vn91YN2qNqb+gGJeZe2+l+TNxVmEEiRHXXnIn2Y40h8=
81-
github.com/code-payments/ocp-protobuf-api v1.6.1-0.20260325154106-63d4d261070d h1:0FIQ4GHwteUlVnS7SC5KHb5f14ZoVjweAn+bhG9agII=
82-
github.com/code-payments/ocp-protobuf-api v1.6.1-0.20260325154106-63d4d261070d/go.mod h1:tw6BooY5a8l6CtSZnKOruyKII0W04n89pcM4BizrgG8=
81+
github.com/code-payments/ocp-protobuf-api v1.7.1-0.20260401115005-c2265cbd04b0 h1:zQdbkGJKttqckZ8GH66fx0g6D6UB/WHT7z5MNiBHMIE=
82+
github.com/code-payments/ocp-protobuf-api v1.7.1-0.20260401115005-c2265cbd04b0/go.mod h1:tw6BooY5a8l6CtSZnKOruyKII0W04n89pcM4BizrgG8=
8383
github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6 h1:NmTXa/uVnDyp0TY5MKi197+3HWcnYWfnHGyaFthlnGw=
8484
github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
8585
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=

ocp/antispam/guard.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,11 @@ func (g *Guard) AllowDistribution(ctx context.Context, owner *common.Account, is
7474
return allow, nil
7575
}
7676

77-
func (g *Guard) AllowSwap(ctx context.Context, fundingSource swap.FundingSource, owner, fromMint, toMint *common.Account) (bool, error) {
77+
func (g *Guard) AllowSwap(ctx context.Context, fundingSource swap.FundingSource, owner, fromMint, toMint *common.Account, amount uint64, initializesMint bool) (bool, error) {
7878
tracer := metrics.TraceMethodCall(ctx, metricsStructName, "AllowSwap")
7979
defer tracer.End()
8080

81-
allow, reason, err := g.integration.AllowSwap(ctx, fundingSource, owner, fromMint, toMint)
81+
allow, reason, err := g.integration.AllowSwap(ctx, fundingSource, owner, fromMint, toMint, amount, initializesMint)
8282
if err != nil {
8383
return false, err
8484
}

ocp/antispam/integration.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type Integration interface {
2020

2121
AllowDistribution(ctx context.Context, owner *common.Account, isPublic bool) (bool, string, error)
2222

23-
AllowSwap(ctx context.Context, fundingSource swap.FundingSource, owner, fromMint, toMint *common.Account) (bool, string, error)
23+
AllowSwap(ctx context.Context, fundingSource swap.FundingSource, owner, fromMint, toMint *common.Account, amount uint64, initializesMint bool) (bool, string, error)
2424

2525
AllowCurrencyLaunch(ctx context.Context, owner *common.Account, name, symbol string) (bool, string, error)
2626
}
@@ -49,7 +49,7 @@ func (i *allowEverythingIntegration) AllowDistribution(ctx context.Context, owne
4949
return true, "", nil
5050
}
5151

52-
func (i *allowEverythingIntegration) AllowSwap(ctx context.Context, fundingSource swap.FundingSource, owner, fromMint, toMint *common.Account) (bool, string, error) {
52+
func (i *allowEverythingIntegration) AllowSwap(ctx context.Context, fundingSource swap.FundingSource, owner, fromMint, toMint *common.Account, amount uint64, initializesMint bool) (bool, string, error) {
5353
return true, "", nil
5454
}
5555

ocp/common/account.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,9 +546,14 @@ type LaunchpadCurrencyAccounts struct {
546546
VaultMint *Account
547547
VaultMintBump uint8
548548
Alt *Account
549+
Seed *Account
549550
}
550551

551552
func GetLaunchpadCurrencyAccounts(metadataRecord *currency.MetadataRecord) (*LaunchpadCurrencyAccounts, error) {
553+
seed, err := NewAccountFromPublicKeyString(metadataRecord.Seed)
554+
if err != nil {
555+
return nil, err
556+
}
552557
authority, err := NewAccountFromPublicKeyString(metadataRecord.Authority)
553558
if err != nil {
554559
return nil, err
@@ -590,6 +595,7 @@ func GetLaunchpadCurrencyAccounts(metadataRecord *currency.MetadataRecord) (*Lau
590595
VaultMint: vaultMint,
591596
VaultMintBump: metadataRecord.VaultMintBump,
592597
Alt: alt,
598+
Seed: seed,
593599
}, nil
594600
}
595601

ocp/common/mint.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ var (
2323
CoreMintName = config.CoreMintName
2424
CoreMintSymbol = config.CoreMintSymbol
2525

26+
CoreMintAlt, _ = NewAccountFromPublicKeyString(config.CoreMintAltPublicKeyString)
27+
2628
ErrUnsupportedMint = errors.New("unsupported mint")
2729

2830
supportedMintCacheMu sync.RWMutex

ocp/config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ const (
2323
CoreMintVmAccountPublicKey = "JACkaKsm2Rd6TNJwH4UB7G6tHrWUATJPTgNNnRVsg4ip"
2424
CoreMintVmOmnibusPublicKey = "D8oUTXRvarxhx9cjYdFJqWAVj2rmzry58bS6JSTiQsv5"
2525

26+
CoreMintAltPublicKeyString = "4oLVyayQJCoPcrkKapE5Ry6pP6vTTTneLP5UPUSQZsvT"
27+
2628
CurrencyAssetsBaseUrl = "https://currency-assets.flipcash-infra.net"
2729
CurrencyAssetsS3BucketName = "flipcash-currency-assets"
2830
)

ocp/data/currency/model.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ const (
1414
MetadataStateAvailable
1515
MetadataStateWaitingForInitialPurchase
1616
MetadataStateFundingAuthority
17-
MetadataStateInitializing
17+
MetadataStateExecutingInitialPurchase
18+
MetadataStateCompletingInitialization
1819
MetadataStateFinalValidation
1920
)
2021

@@ -343,8 +344,10 @@ func (s MetadataState) String() string {
343344
return "waiting_for_initial_purchase"
344345
case MetadataStateFundingAuthority:
345346
return "funding_authority"
346-
case MetadataStateInitializing:
347-
return "initializing"
347+
case MetadataStateExecutingInitialPurchase:
348+
return "executing_initial_purchase"
349+
case MetadataStateCompletingInitialization:
350+
return "completing_initialization"
348351
case MetadataStateFinalValidation:
349352
return "final_validation"
350353
}

ocp/data/currency/tests/tests.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,8 @@ func testCountMetadataByState(t *testing.T, s currency.Store) {
601601
currency.MetadataStateAvailable,
602602
currency.MetadataStateWaitingForInitialPurchase,
603603
currency.MetadataStateFundingAuthority,
604-
currency.MetadataStateInitializing,
604+
currency.MetadataStateExecutingInitialPurchase,
605+
currency.MetadataStateCompletingInitialization,
605606
currency.MetadataStateFinalValidation,
606607
} {
607608
count, err := s.CountMetadataByState(ctx, state)
@@ -680,8 +681,8 @@ func testCountMetadataByState(t *testing.T, s currency.Store) {
680681
require.NoError(t, err)
681682
assert.EqualValues(t, 1, count)
682683

683-
// Move record2 to initializing
684-
record2.State = currency.MetadataStateInitializing
684+
// Move record2 to completing initializing
685+
record2.State = currency.MetadataStateCompletingInitialization
685686
require.NoError(t, s.SaveMetadata(ctx, record2))
686687

687688
count, err = s.CountMetadataByState(ctx, currency.MetadataStateUnknown)
@@ -692,7 +693,7 @@ func testCountMetadataByState(t *testing.T, s currency.Store) {
692693
require.NoError(t, err)
693694
assert.EqualValues(t, 1, count)
694695

695-
count, err = s.CountMetadataByState(ctx, currency.MetadataStateInitializing)
696+
count, err = s.CountMetadataByState(ctx, currency.MetadataStateCompletingInitialization)
696697
require.NoError(t, err)
697698
assert.EqualValues(t, 1, count)
698699
}

ocp/data/internal.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ type DatabaseData interface {
224224
GetSwapById(ctx context.Context, id string) (*swap.Record, error)
225225
GetSwapByFundingId(ctx context.Context, fundingId string) (*swap.Record, error)
226226
GetAllSwapsByOwnerAndState(ctx context.Context, owner string, state swap.State) ([]*swap.Record, error)
227+
GetAllSwapsByOwnerMintAndState(ctx context.Context, owner string, mint string, state swap.State) ([]*swap.Record, error)
227228
GetAllSwapsByState(ctx context.Context, state swap.State, opts ...query.Option) ([]*swap.Record, error)
228229
GetSwapCountByState(ctx context.Context, state swap.State) (uint64, error)
229230

@@ -803,6 +804,9 @@ func (dp *DatabaseProvider) GetSwapByFundingId(ctx context.Context, fundingId st
803804
func (dp *DatabaseProvider) GetAllSwapsByOwnerAndState(ctx context.Context, owner string, state swap.State) ([]*swap.Record, error) {
804805
return dp.swaps.GetAllByOwnerAndState(ctx, owner, state)
805806
}
807+
func (dp *DatabaseProvider) GetAllSwapsByOwnerMintAndState(ctx context.Context, owner string, mint string, state swap.State) ([]*swap.Record, error) {
808+
return dp.swaps.GetAllByOwnerMintAndState(ctx, owner, mint, state)
809+
}
806810
func (dp *DatabaseProvider) GetAllSwapsByState(ctx context.Context, state swap.State, opts ...query.Option) ([]*swap.Record, error) {
807811
req, err := query.DefaultPaginationHandler(opts...)
808812
if err != nil {

0 commit comments

Comments
 (0)